我想运行经典测试来反转列表。为此,我必须将列表专门化为“任意”(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]
在这里不起作用。
是否有一个不那么详细的解决方案?
答案 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才会更好。