runState (modify (+1) >> modify (+1)) 0
上記のコードが(()、2)をどのように生成するか説明できますか? (>>) :: Monad m => m a -> m b -> m b
があれば、最初の "modify(+1)"は(()、1)という結果になると考えられます。ハスケル(>>)演算子
runState (modify (+1) >> modify (+1)) 0
上記のコードが(()、2)をどのように生成するか説明できますか? (>>) :: Monad m => m a -> m b -> m b
があれば、最初の "modify(+1)"は(()、1)という結果になると考えられます。ハスケル(>>)演算子
>>
演算子は、類似の型シグネチャを持つ場合でも、flip const
ではありません。あなたはデフォルトの実装を見れば、あなたはそれが実際にはその最初の引数に>>=
を呼び出して見ることができます:
a >> b = a >>= \_ -> b
そのため、あなたはその「副作用」のためのモナドアクションを実行しているとして>>
と考えることができますが、結果を破棄する。。
runState (modify (+1) >>= \_ -> modify (+1)) 0
これは明らかに、状態モナドのコンテキストで二回modify (+1)
を実行しますので、結果の状態は2
になります:あなたはあなたの例の代わりに>>
の上記の定義をインライン化した場合、あなたが得る結果はかなり明確になります、1
ではありません。
あなたがようなものについて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)