如何插入测试代码

时间:2015-11-15 17:35:51

标签: haskell testing

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

e.g。我试图改变:

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中,用块{..; a}替换代码,在这种情况下,块将被评估为" a"。在Haskell有可能吗?

2 个答案:

答案 0 :(得分:1)

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

peuple :: Int -> Arbre

调用此函数的用户(或其他代码)应该期望给函数Int,并返回Arbre。我们不希望它做任何其他事情。现在您想要的是在此函数中发生效果(或效果):您想要将值打印到控制台。在类型签名中你可以告诉该函数执行某种效果吗?你不会。这是哈斯克尔的禁忌。

只要保留引用透明度,Haskell就允许我们执行效果。将某些内容打印到控制台将涉及使用IO monad。但是IO monad是"单向":一旦你有IO a,你就不能提取a并放弃IO容器,这样函数的类型不会提到IO monad。如果可以的话,那么你已经编写了一个执行效果的功能,但并没有让它发挥作用。因此,如果您希望函数表示返回IO Arbre的计算,但是执行某些效果(如打印到控制台),则必须编写一个返回Arbre的函数。

我第二次mb21建议查看LYAH或另一本解释monad的简介,特别是IO monad。

更重要的是,引用透明度是将print ...投入代码不是Haskell中的选项的主要原因。如果要调试代码,可以使用GHCI调试器。如果您想测试代码,可以使用QuickCheck之类的工具。或者寻找其他用于调试和测试代码的工具。但是花时间了解monad是关键所在。

答案 1 :(得分:0)

db.cupcakes.aggregate([
    { 
        "$match": { "features.properties.gluten free" : "no" }
    },
    { 
        "$redact": {
            "$cond": {
                "if": {
                    "$eq": [ "$gluten free", "yes" ] 
                },
                "then": "$$PRUNE",
                "else": "$$DESCEND"
            }
        }
    }
]).map(function(doc){ return doc.features; });

应该是

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

因为缩进很重要。