Документация гласит:
Прагма {- # INLINABLE f # -} для функции f имеет следующее поведение:
В то время как INLINE говорит «пожалуйста, вставьте меня», INLINABLE говорит «не стесняйтесь, вставьте меня; используйте ваше усмотрение». Другими словами, выбор остается за GHC, который использует те же правила, что и для функций без прагмы. В отличие от INLINE, это решение принимается на месте вызова и поэтому будет зависеть от порога встраивания, уровня оптимизации и т. Д.
Как и INLINE, прагма INLINABLE сохраняет копию исходной RHS для целей вставки и сохраняет ее в файле интерфейса независимо от размера RHS.
Один из способов использования INLINABLE связан со специальной встроенной функцией (раздел 7.18, «Специальные встроенные функции»). Вызов inline f очень старается встроить f. Чтобы убедиться, что f может быть встроенным, рекомендуется пометить определение f как INLINABLE, чтобы GHC гарантировал раскрытие разворачивания независимо от его размера. Более того, аннотируя f как INLINABLE, вы гарантируете, что исходная RHS f встроена, а не какая-либо случайно оптимизированная версия оптимизатора f GHC.
Прагма INLINABLE также работает со SPECIALIZE: если вы пометите функцию f как INLINABLE, вы можете впоследствии SPECIALIZE в другом модуле (см. Раздел 7.16.8, «Прагма SPECIALIZE»).
В отличие от INLINE, можно использовать прагму INLINABLE в рекурсивной функции. Основная причина заключается в том, чтобы разрешить дальнейшее использование SPECIALIZE
В чем его недостаток?
Делает ли он интерфейсные файлы намного, намного больше? Это делает компиляцию намного медленнее?
Есть ли причина, по которой я не должен ставить прагму INLINABLE для каждой экспортируемой функции, которую я пишу? Есть ли причина, по которой GHC не помещает прагму INLINABLE в каждую экспортируемую функцию, которую я пишу?