haskell - 如何插入测试代码

标签 haskell testing

如何在我的函数中添加一些测试代码?

例如我试图改变:

peuple i =
  let parcours = ...

通过:

peuple i =
  do putStrLn $ "entering peuple " ++ i
  let parcours = ...

但是我得到一个解析错误。

编辑

我试过这段代码:

peuple :: Int -> Arbre
peuple 1 = Feuille
peuple i =
  do
    print ("entering peuple " ++ show i)
    ...

但是 ghc 提示该方法应该返回一个“Arbre”而不是一个“IO”……

更一般地说,这是可能的,例如在 scala 中,用 block {..;a} 替换代码,在这种情况下, block 将被评估为“a”。这在 Haskell 中可行吗?

最佳答案

Haskell 是一种纯粹的语言,因为 Haskell 中的函数是引用透明的。查看 peuple 的类型:

peuple :: Int -> Arbre

调用此函数的用户(或其他代码)应该期望为该函数提供一个 Int,并返回一个 Arbre。我们不希望它做任何其他事情。现在你似乎想要的是在这个函数中产生一个(或多个)效果:你想要将值打印到控制台。您可以在类型签名的哪个位置看出此函数执行某种效果?你不会。这是 Haskell 的禁忌。

只要保持参照透明性,Haskell 就允许我们执行效果。将内容打印到控制台将涉及使用 IO monad。但是 IO monad 是“单向”的:一旦你有了一个 IO a,你就不能只提取 a 并抛弃 IO 容器,因此函数的类型与 IO monad 无关。如果可以,那么您会编写一个函数来执行效果但不会让它这样做。因此,如果您希望函数表示返回 Arbre 的计算,但执行某些效果(例如打印到),则必须编写一个返回 IO Arbre 的函数控制台。

我赞成 mb21 的建议,看看 LYAH 或其他介绍 monad 的书籍,尤其是 IO monad。

更重要的是,引用透明性是将 print ... 放入您的代码中的主要原因,这在 Haskell 中不是一个选项。如果你想调试代码,你可以使用 GHCI 调试器。如果你想测试代码,可以使用像 QuickCheck 这样的工具。或者寻找其他工具来调试和测试代码。但是花时间学习 monad 是这里的关键。

关于haskell - 如何插入测试代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33722740/

相关文章:

java - 如何使用gradle打包测试并从命令行运行?

android - Espresso 测试 - Android

java - 如何评估 Web 应用程序的性能和可用性

haskell - 为什么在代数数据类型中,如果我可以为两种类型定义一个特殊的 `from` 和 `to` 函数,这两种类型就可以认为是相等的?

haskell - 如何用foldl实现zip(用一种急切的语言)

haskell - 如何提取这个多态递归函数?

haskell - Happstack中间件缺乏?

haskell - 如何在haskell newtype中定义一个函数?

testing - 测试具有 URLConnection 的方法的最简单方法是什么

android - 从 Robotium 测试用例中的错误线程异常调用