В документации указано:
An {- # INLINABLE f # -} прагма для функции f имеет следующее поведение:
В то время как INLINE говорит: "Пожалуйста, включите меня", INLINABLE говорит: "Не стесняйтесь меня, используйте свое усмотрение". Другими словами, выбор остается для GHC, который использует те же правила, что и для функций без прагмы. В отличие от INLINE, это решение принимается на сайте вызова и поэтому будет зависеть от порога вложения, уровня оптимизации и т.д.
Как и INLINE, прагма INLINABLE сохраняет копию оригинальной RHS для встраивания целей и сохраняется в файле интерфейса независимо от размера RHS.
Один из способов использования INLINABLE - в сочетании со специальной встроенной функцией (раздел 7.18, "Специальные встроенные функции" ). Вызов inline f очень сильно пытается встроить f. Чтобы убедиться, что f может быть встроен, рекомендуется пометить определение f как INLINABLE, чтобы GHC гарантировал возможность разоблачения независимо от того, насколько он большой. Кроме того, аннотируя f как INLINABLE, вы гарантируете, что f оригинальная RHS встроена, а не какая-либо оптимизированная оптимизированная версия оптимизатора GHC.
ПРОГРАММА INLINABLE также работает со SPECIALIZE: если вы помечаете функцию f как INLINABLE, вы можете впоследствии СПЕЦИАЛИЗИРОВАТЬСЯ в другом модуле (см. раздел 7.16.8, "СПЕЦИАЛИЗАЦИЯ прагмы" ).
В отличие от INLINE, можно использовать INLINABLE прагму для рекурсивной функции. Основная причина заключается в том, чтобы впоследствии использовать SPECIALIZE
В чем его недостаток?
Он делает файлы интерфейса намного, намного больше? Делает ли компиляцию намного медленнее?
Есть ли какая-то причина, по которой я не должен помещать INLINABLE прагму для каждой экспортируемой функции, которую я пишу? Есть ли какая-либо причина, по которой GHC не помещает INLINABLE прагму для каждой экспортируемой функции, которую я пишу?