1

我想运行经典测试来反转列表。为此,我必须将列表专门化为“任意”(原文如此!)类型的列表,例如 [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]

在这里不起作用。

有没有更简洁的解决方案?

4

1 回答 1

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 []

并且它仍然会被删除,可以说最好仅在类型检查后删除未使用的让。

于 2014-11-22T14:33:38.377 回答