我一直在一点一点地学习一些 Haskell,并且正在(慢慢地)致力于理解 State monad,尝试编写一个重复状态计算的函数,直到状态满足一些布尔测试,并将返回的值收集到一个列表中以获得整体结果. 我终于成功了:
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]
这是该任务的合理功能,还是有更惯用的方法?