2

我正在研究Real World Haskell第 4 章的练习之一是实现一个foldr基于版本的 concat. 我认为这将是使用 QuickCheck 进行测试的绝佳候选者,因为有一个现有的实现来验证我的结果。然而,这需要我定义一个 Arbitrary可以生成任意[[Int]]. 到目前为止,我一直无法弄清楚如何做到这一点。我的第一次尝试是:

module FoldExcercises_Test
where

import Test.QuickCheck
import Test.QuickCheck.Batch

import FoldExcercises

prop_concat xs = 
    concat xs == fconcat xs
    where types = xs ::[[Int]]


options = TestOptions { no_of_tests = 200
                      , length_of_tests = 1
                      , debug_tests = True }

allChecks = [ 
              run (prop_concat)
            ]

main = do
  runTests "simple" options allChecks

这导致不执行任何测试。看着各种点点滴滴,我猜想Arbitrary需要并添加一个实例声明

    instance Arbitrary a => Arbitrary [[a]] where
    arbitrary = sized arb' 
        where arb' n = vector n (arbitrary :: Gen a)

这导致 ghci 抱怨我的实例声明无效并且添加 -XFlexibleInstances 可能会解决我的问题。添加{-# OPTIONS_GHC -XFlexibleInstances #-}指令会导致类型不匹配和重叠实例警告。

所以我的问题是要完成这项工作需要什么?我显然是 Haskell 的新手,没有找到任何可以帮助我的资源。任何指针都非常感谢。

编辑

fconcat当在测试优先方式中定义 为时,我似乎被 QuickCheck 的输出误导了

fconcat = undefined  

实际正确实现该功能确实给出了预期的结果。糟糕

4

1 回答 1

3

[[Int]]已经是一个Arbitrary实例(因为Int是一个Arbitrary实例,所以[a]对于所有a本身就是 的实例的 s 也是如此Arbitrary)。所以这不是问题。

我自己运行了你的代码(用 替换import FoldExcercisesfconcat = concat,它运行了 200 次测试,正如我所预料的那样,所以我对它为什么不为你做这件事感到困惑。但是您不需要添加Arbitrary实例。

于 2009-11-06T23:24:14.620 回答