我有一个小任务来模拟涉及状态的单子代码中的命令式循环,并且应该没有 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