如果我有一个随机播放“纸牌”的函数,我该如何使用State Monad
来遍历已定义的随机播放次数,然后返回结果?
例如,我具有以下功能,该功能将先对卡片组进行1次随机播放,然后返回特定的卡片:
step :: State [String] String
step = do
modify shuffle
deck <- get
pure $ bestCard deck
我想做的是在返回值之前对状态更改进行5次迭代。
我尝试过的是这个
steps :: Int -> State [String] String
steps n = case n of
0 -> do
deck <- get
pure $ bestCard deck
_ -> do
modify shuffle
steps (n - 1)
但这看起来远不是正确的方法,即使它可行。
NB。我知道可以不使用State Monad
来完成此操作,但是我正在尝试使用此示例来学习如何使用State
。
编辑:
由于@Koterpillar,我可以使用replicateM
来获得想要的东西。
evalState (replicateM n $ modify shuffle >> get >>= pure . bestCard)
答案 0 :(得分:8)
最简洁的方法是replicateM_
,它会重复执行一次monadic操作指定的次数并丢弃结果:
replicateM_ 5 $ modify shuffle
因为State是一个monad,所以您只需要关心重复操作,而不必专门与State合作。我通过searching Hoogle找到了我想要的功能的签名的上述功能:
Monad m => Int -> m a -> m ()
请注意,结果甚至不需要单子,而仅是可应用的:
replicateM_ :: Applicative m => Int -> m a -> m ()