У меня есть модуль, который собирает и экспортирует кучу небольших функций, таких как:
fromEither :: (MonadError e m) => Either e a -> m a
fromEither = either throwError return
или
withError :: MonadError e m => (e -> e) -> m a -> m a
withError = flip catchError (throwError . f)
Это хорошая идея, чтобы они были встроены, так как после специализации на конкретный экземпляр MonadError
, вероятно, много кода будет оптимизировано.
В документации GHC говорится:
GHC (с
-O
, как всегда) пытается встраивать (или "разворачивать" ) функции/значения, которые являются "достаточно маленькими", что позволяет избежать накладных расходов и, возможно, подвергать другие более прекрасные оптимизации. Обычно, если GHC решает, что функция "слишком дорогая" для встроенного, она не будет делать этого, и не будет экспортировать это разворачивание для использования других модулей.
Означает ли это, что такие функции, скорее всего, будут обрабатываться так, как если бы они имели прагму INLINE
(т.е. их неоптимизированный RHS, записанный в файле интерфейса)? Или мне нужно добавить INLINE
себя? Добавляет ли это что-либо (что, если GHC решает, что они "достаточно малы" )?
Я не возражаю, если GHC решит не включать некоторые из моих функций, если он считает, что они слишком дороги, но в целом я хотел бы, чтобы они были встроены без загрязнения моего исходного кода, добавив INLINE
всюду.