这是以下文档的摘录evaluate
:
Control.Exception.Base.evaluate :: a -> IO a
evaluate x
不一样
return $! x
一个正确的定义是
evaluate x = (return $! x) >>= return
(来源)
这些似乎具有相同的含义。这两个定义有什么区别?
快速参考:
的类型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
定义,上面的表达式将导致未定义的异常。这有值⊥,不等于 42。
根据(return $! x) >>= return
定义,它确实等于 42。
基本上,在return $! x
计算 IO 值时,形式是严格的。另一种形式仅在运行 IO 值和使用的值(使用>>=
)时是严格的。
有关更多详细信息,请参阅此邮件列表线程。