我一点一点地学习Haskell,并且正在努力理解State monad,试图编写一个函数,重复执行State计算,直到状态满足某个布尔测试,并将返回的值收集到列表中以获得总体结果。 最终我成功了:
collectUntil :: (s -> Bool) -> State s a -> State s [a]
collectUntil f s = do s0 <- get
let (a,s') = runState s s0
put s'
if (f s') then return [a] else liftM (a:) $ collectUntil f s
为了...
simpleState = state (\x -> (x,x+1))
*Main> evalState (collectUntil (>10) simpleState) 0
[0,1,2,3,4,5,6,7,8,9,10]
这个函数是否适合完成这个任务,或者有更符合习惯的方法?
Monad m => m Bool -> m a -> m [a]
。使用monad-loops
中的untilM
,您可以得到:untilM simpleState (liftM (> 10) get)
。 - Vitus