【问题标题】:How to generate arbitrary two argument function with QuickCheck?如何使用 QuickCheck 生成任意两个参数函数?
【发布时间】:2018-02-11 11:31:20
【问题描述】:

我正在尝试使用 QuickCheck 测试我对 zipWith 的实现。我的实现,myZipWith,我想通过与标准函数进行比较来进行 QuickCheck 测试。比如:

main = do
  quickCheck (prop_myZipWith :: (Int -> Int -> Int) -> [Int] -> [Int] -> Bool)

prop_myZipWith :: (a -> b -> c) -> [a] -> [b] -> Bool
prop_myZipWith f x y = (myZipWith x y) == (zipWith f x y)

这不起作用,因为(Int -> Int -> Int) 不是Arbitrary 的实例。

使用单参数函数,可以使用Test.QuickCheck.FunctionFun(它实例化Arbitrary)来解决这个问题。例如:

main = do
  quickCheck (prop_myMap :: Fun Int Int -> [Int] -> Bool)

prop_myMap :: Fun a b -> [a] -> Bool
prop_myMap (Fun _ f) l = (myMap f l) == (map f l)

我正在尝试做类似的事情,除了生成两个-参数任意函数。

如何生成两个参数函数的任意实例,以便对 zipWith 等高阶函数进行 QuickCheck 测试?

【问题讨论】:

  • 你不能仅仅利用柯里化并使用Fun Int (Fun Int Int)吗?请记住,没有二进制函数这样的东西,因为一切都是柯里化的。
  • 请注意语句“这不起作用,因为 (Int -> Int -> Int) 不是 Arbitrary 的实例。”为假(函数 的任意实例)。它不起作用,因为函数不是Show 的实例。但正如@chi 所说,currying 以一种微不足道的方式解决了你的问题(而且也以Fun (Int, Int) Int 也可以工作的唯一稍微不那么微不足道的方式)。您可能会发现 unFun (Fun _ f) = f; unFun2 f = unFun . unFun f 的定义很有用。
  • @chi,我有限的实践经验表明,Fun (a,b,...) xFun a (Fun b (... x ...)) 工作起来更痛苦
  • 如果您的下一个问题是“高阶函数呢?”,那也是我的问题。但这似乎非常困难。 Koen Claessen 无法找到令人满意的解决方案,因此您应该仅在需要研究项目时才考虑它。

标签: haskell quickcheck


【解决方案1】:

快速检查 2.9.2

使用 QuickCheck 2.9.2,您可以使用 Fun 类型和 Fn 模式。你必须

import Test.QuickCheck.Function

然后您可以使用元组作为输入来编写属性,然后 curry 函数:

prop_myZipWith :: Eq c => Fun (a, b) c -> [a] -> [b] -> Bool
prop_myZipWith (Fn f) x y = myZipWith (curry f) x y == zipWith (curry f) x y

main 看起来像这样:

main =
  quickCheck (prop_myZipWith :: Fun (Int, Int) Int -> [Int] -> [Int] -> Bool)

在我的 repro 中编译,测试通过。

快速检查 2.10.0.1

使用 QuickCheck 2.10.0.1,您可以改用 Fn2 模式,如下所示:

prop_myZipWith :: Eq c => Fun (a, b) c -> [a] -> [b] -> Bool
prop_myZipWith (Fn2 f) x y = myZipWith f x y == zipWith f x y

main 方法保持不变,因为prop_myZipWith 的类型没有改变,但不再需要import Test.QuickCheck.Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    相关资源
    最近更新 更多