1

我有两个函数foo必须满足的属性:

prop_1 :: [Int] -> Bool
prop_1 xs = foo xs id == xs 

prop_2 :: [Int] -> (Int -> Int) -> (Int -> Int) -> Bool
prop_2 xs f g = foo (foo xs f) g == foo xs (g . f)

我正在尝试使用 quickCheck 检查上述属性是否满足以下功能:

foo :: [a] -> (a -> b) -> [b]
foo xs f = []

当我尝试使用 prop_2 运行 quickCheck 时,出现以下错误:

quickCheck(prop_2)

<interactive>:18:1: error:
     No instance for (Show (Int -> Int))
        arising from a use of 'quickCheck'
        (maybe you haven't applied a function to enough arguments?)
     In the expression: quickCheck (prop_2)
      In an equation for 'it': it = quickCheck (prop_2)

我不确定为什么会收到此错误以及如何解决它。任何见解都值得赞赏。

4

2 回答 2

2

您可以使用 QuickCheck 对生成随机可收缩、可显示函数的支持,方法是将属性更改为

prop_2 :: [Int] -> Fun Int Int -> Fun Int Int -> Bool
prop_2 xs (Fn f) (Fn g) = foo (foo xs f) g == foo xs (g . f)

然后你会看到比<function>反例更有用的东西。

于 2019-06-28T10:47:54.730 回答
1

正如文档QuickCheck所说:

但是,在我们测试这样的属性之前,我们必须确保可以打印函数值(以防找到反例)。也就是说,函数类型必须是 class 的实例Show。为此,您必须将模块导入ShowFunctions到每个包含此类高阶属性的模块中。如果找到反例,函数值将显示为"<function>"

因此,您可以通过导入如下模块来解决此问题:

import Text.Show.Functions

prop_1 :: [Int] -> Bool
prop_1 xs = foo xs id == xs 

prop_2 :: [Int] -> (Int -> Int) -> (Int -> Int) -> Bool
prop_2 xs f g = foo (foo xs f) g == foo xs (g . f)
于 2019-06-28T10:20:12.313 回答