2012-03-04 14 views
21

評価文書の抽出:"評価" ここ機能

evaluate x 

return $! x 

と同じではない (http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Control-Exception-Base.html#v:evaluateが参照)正しい定義は

evaluate x = (return $! x) >>= return 
あります

私はこの2つの定義の意味の違いを理解していません... 私を助けることができる人がいますか? ありがとうございます!

+4

これは実際にモナド法に違反していませんか? – leftaroundabout

+2

@leftaroundaboutいいえ、そうではありません。実行されていれば両方とも全く同じように動作しますが、式を 'seq'すると' return $! '(return $!x)>> = return'は'(>> =) 'をもっています。 –

+4

@leftaroundabout:いいえ、⊥は法律上無視されるためです。 'Reader'のような標準的なモナドも同じように動作します。 (私が他の人から聞いたことのあるダニエル・フィッシャーの議論を買わないのは、「実行すれば全く同じように行動する」というのは、明確な概念ではないからです。) – ehird

答えて

19

クイック参照:

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を参照してください。

+0

'(return $!undefined)>> = return'と' return $!とは異なるのはなぜですか?定義されていない?私の推測では、前者は、 '(($ return $ undefined)>> = return)\' seq \ '42'で' undefined'が評価されないように間接指定を追加しています。 – mucaho