Какова семантика "строгих возвратов"?

В Haskell Performance Resource вики-раздел, дальнейшая поясняемая рекомендация дается

  • Используйте строгие возвраты (return $! ...), если они вам не нужны.

Почему это хорошо? Когда именно выражение ... -expression (Whnf-) принудительно?

Учитывая монад-закон "левой личности" и определение

f $! x = x `seq` f x

Я могу переписать (в do -notation`):

do x' <- return $! x
   f x'

к

do x' <- x `seq` return x
   f x'

Но, похоже, я не могу добраться до

do f $! x

PS: Если доступно расширение BangPatterns, это

do !x' <- return x
   f x'

семантически совпадает с первым выражением do, приведенным выше?

Ответ 1

Есть причина, по которой вы не можете получить

do x' <- x `seq` return x
   f x'

к

f $! x

Это потому, что они не то же самое. Просто добавьте обозначения:

(x `seq` return x) >>= (\ x' -> f x')

seq будет оцениваться только в том случае, если (>>=) является строгим в своем первом аргументе. Это не обязательно верно.

Ответ 2

Для IO есть также полезный Control.Exception.evaluate:

Заставляет аргумент оцениваться как слабая нормальная форма головы, когда результат выполнения ИО выполнен. Это может использоваться для оценки в отношении других операций ввода-вывода; его семантика дается выражением

evaluate :: a -> IO a
evaluate x = (return $! x) >>= return