2014-11-22 52 views
1

我想運行反轉列表的經典測試。爲此,我必須將列表專門化爲「任意」(sic!)類型的列表,例如, [INT]。我該如何專注於Frege QuickCheck中的類型?

什麼工作是

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

這是不幸的是,

where types = xs :: [Int] 

通過讓表達簡化和標準化通,甚至類型檢查之前,其附帶除去得到的情況。 這就是說,依賴性分析的一個副作用,其中看到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 [] 

,它仍然會得到去除,那就可以說是更好只有在類型檢查後才能刪除未使用的讓。

+0

太棒了!謝謝 – Dierk 2014-11-22 14:37:47

+2

我沒有試過這個,但是你可以在'reverse'上貼上一個類型簽名嗎? 'property(\ xs - >(reverse :: [Int] - > [Int])(reverse xs)== xs)' – dfeuer 2014-11-22 14:48:00

+0

@dfeuer正確,只要它粘在類型簽名的哪裏並不重要不在未使用的let/where定義中,並且可以從中派生'xs'的類型。 – Ingo 2014-11-22 14:50:29