23

这是以下文档的摘录evaluate

Control.Exception.Base.evaluate :: a -> IO a
evaluate x

不一样

return $! x

一个正确的定义是

evaluate x = (return $! x) >>= return

来源

这些似乎具有相同的含义。这两个定义有什么区别?

4

1 回答 1

21

快速参考:

的类型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 值和使用的值(使用>>=)时是严格的。

有关更多详细信息,请参阅此邮件列表线程

于 2012-03-04T12:49:21.183 回答