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