Какова семантика "строгих возвратов"? - PullRequest
11 голосов
/ 10 апреля 2011

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

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

Почему это хорошо? Когда именно ... -выражение (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 выражением, приведенным выше?

Ответы [ 2 ]

5 голосов
/ 10 апреля 2011

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

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

до

f $! x

Это потому, что они не одинаковы. Просто разверните обозначение do:

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

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

1 голос
/ 10 апреля 2011

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

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

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