Ответ 1
Быстрая ссылка:
Тип evaluate
:
evaluate :: a -> IO a
seq
имеет тип a -> b -> b
. Сначала он оценивает первый аргумент, затем возвращает второй аргумент.
Вычислить следующие три правила:
evaluate x `seq` y ==> y
evaluate x `catch` f ==> (return $! x) `catch` f
evaluate x >>= f ==> (return $! x) >>= f
Различие между return $! x
и (return $! x) >>= return
становится очевидным с помощью этого выражения:
evaluate undefined `seq` 42
По первому правилу, которое должно оцениваться до 42.
С помощью определения return $! x
приведенное выше выражение вызовет исключение undefined. Это имеет значение ⊥, которое не равно 42.
При определении (return $! x) >>= return
оно равно 42.
В принципе, форма return $! x
является строгой, когда вычисляется значение ввода-вывода. Другая форма является строгой только при выполнении значения ввода-вывода и используемого значения (используя >>=
).
Подробнее см. этот список рассылки.