测试Monadic代码

时间:2014-09-21 14:59:43

标签: haskell monads

我正在通过Haskell course by Brent Yorgey学习Haskell。我刚刚到达monad部分,虽然我认为我(最后)对如何使用monad有一个很好的把握,但我不明白如何测试使用它们的代码。

本节的练习是编写一个(简化的)风险模拟,它需要大量使用Rand StdGen monad。特别是,我们必须编写以下函数:

type Army = Int

data Battlefield = Battlefield { attackers :: Army, defenders :: Army }

battle :: Battlefield -> Rand StdGen Battlefield

它需要一个初始战场,并模拟这场战斗将如何进行。

我有一个实现,但我不明白如何测试它。我无法“了解”Rand StdGen Battlefield返回的battle内的值,所以我无法在GHCI解释器上打印出来,这就是我到目前为止测试代码的方式。我也无法弄清楚如何在Haskell主函数或其他东西中打印战斗结果。人们如何测试这些功能?

1 个答案:

答案 0 :(得分:10)

你可以"到达"使用evalRand和朋友等函数进行随机计算的结果。 evalRand需要一个'开始' RandomGen并确定性地运行monadic计算。


这是我对evalRand所针对的那些挥手,不严谨的解释:

monad和命令式编程之间的区别之一是monad是计算的表示,而不是计算本身。换句话说,当Haskell评估像a >>= b >>= c(或等效的do符号)这样的表达式时,它只是将乐高积木放在一起,可以这么说 - 计算并不是这样。发生之前,使用像evalRand这样的函数执行 monad。

对于一个更简单的例子,考虑一起组合函数。 .为您提供了一个函数,该函数表示由它组成的两个函数执行的计算。当您实际使用参数调用函数时,只能从该计算中获得返回值。

这就是为什么标准库中的许多monad(由IO除外,它由运行时系统执行)提供了一个"陷阱门"功能类似于evalRand。这就是你实际使用你在monadic代码中定义的计算的方式。