状態が関与するモナドコードで命令型ループをエミュレートする小さなタスクがあり、IO がないはずです。タスクは条件付きでループを終了することであり、ここに私の試みがあります:
> execState (forever $ modify (+1) >>= \x -> guard $ x < 5 ) 1
したがって、ここでは 4 のようなものが得られると期待していますが、代わりに次の不可解なメッセージが表示されます。
<interactive>:1:43:
No instance for (MonadPlus Data.Functor.Identity.Identity)
arising from a use of `guard' at <interactive>:1:43-47
Possible fix:
add an instance declaration for
(MonadPlus Data.Functor.Identity.Identity)
In the first argument of `($)', namely `guard'
In the expression: guard $ x < 5
In the second argument of `(>>=)', namely `\ x -> guard $ x < 5'
全体はガードなしで問題なく動作しますが、何らかの理由で完全にガードが嫌いなようです。
UPD : 最後に、タイプのヒントを提供してくれた hammar のおかげで、実行できるようになりました。何も返さないにもかかわらず、5回実行されることはわかっています。これはクールですが、今のところどのように役立つかわかりません。
runStateT (forever $ do { modify (+1); x <- get; guard $ x < 5 } :: StateT Int Maybe Int) 1