Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 用Haskell编写不同类型的测试用例_Unit Testing_Haskell_Testing - Fatal编程技术网

Unit testing 用Haskell编写不同类型的测试用例

Unit testing 用Haskell编写不同类型的测试用例,unit-testing,haskell,testing,Unit Testing,Haskell,Testing,我制作了一个创建“类似列表”序列的库,其中实现了许多Prelude样式的函数。我想为此编写一些测试用例,以确保我的库生成正确的输出,我认为最简单的方法是编写一些函数,将结果转换为列表,并将它们与Prelude结果进行比较。假设我们有: import qualified MyLibrary as ML import qualified Prelude as P 例如,我可能需要以下测试用例: P.take 5 (P.enumFrom 1) == toList (ML.take 5 (ML.enu

我制作了一个创建“类似列表”序列的库,其中实现了许多Prelude样式的函数。我想为此编写一些测试用例,以确保我的库生成正确的输出,我认为最简单的方法是编写一些函数,将结果转换为列表,并将它们与Prelude结果进行比较。假设我们有:

import qualified MyLibrary as ML
import qualified Prelude as P
例如,我可能需要以下测试用例:

P.take 5 (P.enumFrom 1) == toList (ML.take 5 (ML.enumFrom 1))
请注意,
ML.enumFrom
不输出列表,而是输出自己的数据类型

上述方法很好,但请注意我是如何“重复我自己”(TM)。我必须确保左侧和右侧是相同的,否则我的测试用例是错误的


有没有一种很好的方法来编写这样的测试用例,这样我就不必重复我自己了?

第一个问题是
p.take
ML.take
等,它们看起来很相似——事实上它们是完全不相关的函数,编译器对它们的常见行为一无所知。因此,正如@jd823592所建议的,我们需要用一个typeclass对它们进行分组(我使用了一个简单的
newtype
包装器,这样示例就可以编译了):

然后,我们将尝试使用类定义中现在统一的函数定义一些测试。它们可能只生成任何类型的
序列
,然后我们将强制它们生成显式类型

test1 = doTest (take 5 $ enumFrom 1) -- the part in brackets is polymorphic

doTest :: (Eq a, Sequence s) => s a -> Bool
doTest test = ???
现在第二个问题是,我们将多态函数作为参数传递,然后需要使用不同的类型参数对其进行实例化(
[a]
在本例中是
MySeq a
)。在standard Haskell 2010中,这是不可能的,但我们可以利用:

{-#语言类型}
多斯特:对于所有a。等式a=>(对于所有序列s=>sa)->Bool
doTest test=(test`asTypeOf`dummy1)=toList(test`asTypeOf`dummy2),其中
dummy1::等式a=>[a]
dummy1=未定义
dummy2::Eq a=>MySeq a
dummy2=未定义

这个解决方案有点笨拙,但仍然有效。请随时改进。

当你的测试定义为“重复自己”时,我不认为你真的是在“重复自己”为了比较两种机制。理想情况下,所有测试都采用一个参数来确定要使用哪个函数,这样我就可以有一个
doTest
函数,类似于
doTest test=test True==toList(test False)
之类的函数,但是我还没有找到一种不让类型检查器讨厌我的方法。@Clinton:我认为如果不实例化一个普通的
,或者不可能使用模板haskell(我没有经验),你就无法做到这一点
test1 = doTest (take 5 $ enumFrom 1) -- the part in brackets is polymorphic

doTest :: (Eq a, Sequence s) => s a -> Bool
doTest test = ???
{-# LANGUAGE Rank2Types #-}

<...>

doTest :: forall a . Eq a => (forall s . Sequence s => s a) -> Bool
doTest test = (test `asTypeOf` dummy1) == toList (test `asTypeOf` dummy2) where
    dummy1 :: Eq a => [a]
    dummy1 = undefined
    dummy2 :: Eq a => MySeq a
    dummy2 = undefined