Haskell:基于属性的高阶函数测试

时间:2019-06-28 10:12:26

标签: haskell functional-programming quickcheck property-based-testing

我有一个函数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)

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

2 个答案:

答案 0 :(得分:2)

通过将属性更改为

,可以使用QuickCheck对generation of random shrinkable, showable functions的支持
InspectorActivate

然后您会看到比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) 更有用的反例。

答案 1 :(得分:1)

正如documentation on QuickCheck所说:

  

但是,在测试这样的属性之前,必须确保可以打印函数值(以防发现反例)。也就是说,函数类型必须是类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)