クイック参照:
evaluate
の種類は次のとおりです。
evaluate :: a -> IO a
seq
はタイプa -> b -> b
を持っています。最初に最初の引数を評価し、次に2番目の引数を返します。
evaluate x `seq` y ==> y
evaluate x `catch` f ==> (return $! x) `catch` f
evaluate x >>= f ==> (return $! x) >>= f
return $! x
と(return $! x) >>= return
の違いは、この表現で明らかになります::42に評価されなければならない最初のルールによって
evaluate undefined `seq` 42
は、これらの3つのルールを以下の評価します。
return $! x
定義の場合、上記の式は未定義例外を引き起こします。これは、IO値を算出する際に42
は基本的に、return $! x
形態は厳密で等しいし、(return $! x) >>= return
定義と同等の42
しない値を⊥、有します。他の形式は、IO値が実行され、使用される値(>>=
を使用)の場合にのみ厳密になります。
詳細については、this mailing list threadを参照してください。
これは実際にモナド法に違反していませんか? – leftaroundabout
@leftaroundaboutいいえ、そうではありません。実行されていれば両方とも全く同じように動作しますが、式を 'seq'すると' return $! '(return $!x)>> = return'は'(>> =) 'をもっています。 –
@leftaroundabout:いいえ、⊥は法律上無視されるためです。 'Reader'のような標準的なモナドも同じように動作します。 (私が他の人から聞いたことのあるダニエル・フィッシャーの議論を買わないのは、「実行すれば全く同じように行動する」というのは、明確な概念ではないからです。) – ehird