Haskell:链接状态Monad

时间:2019-04-29 00:22:44

标签: haskell

如果我有一个随机播放“纸牌”的函数,我该如何使用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)

1 个答案:

答案 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 ()