のドキュメントからの抜粋を次に示しますevaluate
。
Control.Exception.Base.evaluate :: a -> IO a
evaluate x
と同じではありません
return $! x
正しい定義は
evaluate x = (return $! x) >>= return
(ソース)
これらは同じ意味のようです。これら2つの定義の違いは何ですか?
クイックリファレンス:
のタイプevaluate
は次のとおりです。
evaluate :: a -> IO a
seq
タイプを持っていa -> b -> b
ます。最初に最初の引数を評価し、次に 2 番目の引数を返します。
評価は次の 3 つのルールに従います。
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 値を計算するときのフォームは厳密です。もう 1 つの形式は、IO 値が実行され、値が使用される ( を使用>>=
) 場合にのみ厳密です。
詳細については、このメーリング リストのスレッドを参照してください。