【问题标题】:Repeated calling a Haskell monad重复调用 Haskell monad
【发布时间】:2012-06-08 20:51:00
【问题描述】:

我有一个返回 monad 的 Haskell 函数,声明如下:

data Options = Options {
    optGames :: Int,
    optSuits :: Int,
    optVerbose :: Bool
  } deriving Show

playGame :: Options -> StateT StdGen (WriterT [String] IO)) Bool

此函数玩单人纸牌游戏,然后返回一个指示输赢的布尔值,以及WriterT monad 中的日志。

我想调用这个函数一定次数,每次都使用随机生成器 (StdGen) 的“下一个”值,并将 Bool 返回值连接到一个列表中。

我尝试创建一个递归函数来执行调用,但不知道如何将 monad 传递到每个下一次迭代中。

我想效仿

initial state >>= playGame >>= playGame ... -- repeat N times

并收集所有生成的Bool 值,以及来自WriterT monad 的日志条目。

最好的方法是什么?

【问题讨论】:

  • initial state >>= playGame >>= playGame 的类型不正确。我可以猜到你的意思,但如果我不必猜测,我也可以给出更好、更自信的答案:)
  • 它的类型不太好,因为我仍在努力研究应该是什么类型。我已经浏览了所有我能找到的转换器示例,但 Haskell 绝对是我所使用过的最严格的数学语言,而且我很难理解其中的一些示例。

标签: haskell loops monad-transformers


【解决方案1】:

我认为您正在寻找replicateM。这会将给定的操作重复指定次数,并将结果作为列表返回。所以replicateM n playGame 对应于玩游戏n 次并返回结果列表。

【讨论】:

  • 如果我只需要最后一个结果怎么办?有没有它的简写?除了fmap last.
  • @ron:我想不出任何内置函数可以做到这一点,但你自己写应该很容易。
  • 我不明白replicateM 1 playGameinitialState >>= playGame 是如何相同的。我的理解是这些应该是等效的,但是带有replicateM 的版本中缺少initialState。我错过了什么?
猜你喜欢
  • 2016-08-12
  • 2012-10-08
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
相关资源
最近更新 更多