2016-11-25 12 views
2
runState (modify (+1) >> modify (+1)) 0 

上記のコードが(()、2)をどのように生成するか説明できますか? (>>) :: Monad m => m a -> m b -> m bがあれば、最初の "modify(+1)"は(()、1)という結果になると考えられます。ハスケル(>>)演算子

答えて

6

>>演算子は、類似の型シグネチャを持つ場合でも、flip constではありません。あなたはデフォルトの実装を見れば、あなたはそれが実際にはその最初の引数に>>=を呼び出して見ることができます:

a >> b = a >>= \_ -> b 

そのため、あなたはその「副作用」のためのモナドアクションを実行しているとして>>と考えることができますが、結果を破棄する。

runState (modify (+1) >>= \_ -> modify (+1)) 0 

これは明らかに、状態モナドのコンテキストで二回modify (+1)を実行しますので、結果の状態は2になります:あなたはあなたの例の代わりに>>の上記の定義をインライン化した場合、あなたが得る結果はかなり明確になります、1ではありません。

3

あなたがようなものについてState sモナドを行うことができます

newtype State s a = State { runState :: s -> (a, s) } 

とのオペレータ(>>)はこのモナドのために実装されている方法を見てみましょう:

(State f) >> (State g) = State (g . snd . f) 

そして、どのような作業を変更します。

modify f = State $ \s -> ((), f s) 

すべてをまとめて:

その後
modify (+1) >> modify (+1) => (State $ \s -> ((), s + 1)) >> ((State $ \s -> ((), s + 1)) => State (\s -> ((), (s + 1) + 1)) 

runState (State (\s -> ((), (s + 1) + 1))) 0 => (\s -> ((), (s + 1) + 1)) 0 => ((), (0 + 1) + 1) => ((), 2)