7

Haskell のモナドの >> 演算子は、しばしば次のように定義されます。

(>>) :: m a -> m b -> m b
a >> b = a >>= \_ -> b

のようなものを印刷するために使用できます。

main = putStr "foo" >> putStrLn "bar"

コンパイラが の値を最適化せずputStr "foo"、単に評価しないのはなぜputStrLn "bar"ですか? それは必要ないのに、なぜそれを計算するのですか?

4

3 に答える 3

10

クリスが言ったように、それはモナドに依存します。Identityorは、結果の計算に必要ないため、Readerの前の部分を評価しません。、、、またはwill>>のような他のモナド。WriterMaybeEitherStateIO

Maybe例として挙げてみましょう。>>=と定義されている

Nothing  >>= _  = Nothing
(Just x) >>= f  = f x

したがって、展開する>>と、

Nothing  >> _  = Nothing
(Just x) >> y  = y

そのため、結果が または になるかどうかを確認するためMaybeに、 の前にあるものを評価する必要があります。>>Nothingy

IO結果が必要かどうかにかかわらず、アクションが評価されるように意図的に定義されています (そうでなければ、使用することは不可能です)。

于 2012-12-15T21:10:27.983 に答える
6

は?もちろん、 の値が必要ですputStr "foo"。モナド>>=をアクションと考えたい場合は、アクション自体ではなく、アクションの結果のみが破棄されます。

たとえば、パーサーでは、解析されたばかりのシーケンスを破棄することを意味しますが、まだ解析されているため、カーソルはまだ前方に移動しています。

于 2012-12-15T12:55:17.213 に答える
6

それはモナドに依存します。IO では評価されます。Identity では、最初のものは評価されません。

> import Control.Monad.Identity
> import Control.Monad.Trace
> let x = trace "x" $ return () :: Identity ()
> let y = trace "y" $ return () :: Identity ()
> runIdentity $ x >> y
y
()
于 2012-12-15T13:17:19.470 に答える