如何在Frege QuickCheck中专门化一种类型?

时间:2014-11-22 11:44:14

标签: haskell quickcheck frege

我想运行经典测试来反转列表。为此,我必须将列表专门化为“任意”(sic!)类型的列表,例如, [INT]。

什么有效

module ListCheck where

import Test.QuickCheck

myReverse :: [Int] -> [Int]
myReverse = reverse

reverse_of_reverse_is_original = property (\xs -> myReverse(myReverse xs) == xs)

或将像

这样的不变量分解出来
reverse_invariant :: [Int] -> Bool
reverse_invariant xs = reverse(reverse xs) == xs
reverse_of_reverse_is_original = property reverse_invariant

但我宁愿不包装原始函数,而是直接使用它。通常通过添加

强制专业化的Haskell技巧
... where types = xs :: [Int]

在这里不起作用。

是否有一个不那么详细的解决方案?

1 个答案:

答案 0 :(得分:1)

不幸的是,

的情况
where types = xs :: [Int]
通过let表达式简化和规范化传递删除

,它在类型检查之前进行。 可以说,这是依赖性分析的副作用,可以看出types完全没用。

你可以写:

p_rev = property rev
    where rev (xs::[Int]) = (reverse . reverse) xs == xs

甚至:

p_rev = forAll (arbitrary :: Gen [Int])
          (\xs -> (reverse . reverse) xs == xs)

因为有人可以像

那样写废话
where types = 1:true:"foo" + Just []

并且它仍然会被删除,只有在类型检查后删除未使用的let才会更好。