2011-10-05 54 views
1

我開始通過執行99個Haskell問題來學習Haskell。 http://www.haskell.org/haskellwiki/H-99:_Ninety-Nine_Haskell_Problems我想使用quickcheck爲每個程序/函數編寫測試。避免重複的QuickCheck屬性

我有以下代碼:

 
import Test.QuickCheck 
import Text.Printf 

main = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests 

-- 1 
myLast lst = last lst 
prop_1a xs x = myLast (xs ++ [x]) == (x::String) 

myLast' = head . reverse 
prop_1b xs x = myLast' (xs ++ [x]) == (x::String) 

tests = [("1a",     quickCheck prop_1a) 
     ,("1b",     quickCheck prop_1b) 
     ] 

我可能會寫myLast''myLast''',等有沒有一種方法,我可以測試所有這些方法,而不必重複代碼,快速檢查屬性?

相關問題:現在,我告訴quickcheck使用字符串。有沒有辦法隨機使用不同的類型進行測試?

+0

請_永遠_用「法」作爲同義詞「功能」 – alternative

回答

2

有沒有一種方法可以測試所有這些方法,而不必重複代碼和quickcheck屬性?

爲什麼不編寫道具以便它包含一個函數列表,然後對每個函數進行檢查?然後你會運行它作爲quickCheck (myProp [myLast, myLast', myLast''])

編輯:我怕你可能會問:P要做到這一點正如我上面所說,myProp應採取的函數列表,它們都具有相同的類型last,並返回一個布爾值:

myProp :: [([a] -> a)] -> Bool 

但現在,我看它,它可能會更好(更類似於原始的方法)有它也需要一個列表中的項目,所以我想我會做,而不是:

myProp :: [([a] -> a)] -> [a] -> a -> Bool 

如果列表爲空,則返回true:

myProp [] _ _ = True 

如果沒有,那麼我們檢查屬性是否適用於在列表中的第一個函數,然後遞歸檢查列表的其餘部分:

myProp [f:fs] xs x = f (xs ++ [x]) == x && myProp fs xs x 

(我不知道爲什麼要這麼寫x::String在您的實施。我不認爲你應該需要它 - last適用於任何事物的列表,而不僅僅是字符串列表。但我沒有真正測試過,所以我認爲你有一個很好的理由。)

無論如何,我認爲這應該工作,但我沒有真正嘗試過。請隨時編輯並修復我可能做出的任何啞語法錯誤或任何其他錯誤。

+0

我在找出問題的語法做這件事 - 你能修改你的答案來證明嗎? –

+0

我添加了x :: String,因爲我需要在某處提供類型信息。 –

6

只要採取了測試功能,測試的另一種說法:

prop_1 last xs x = last (xs ++ [x]) == (x :: Int) 

tests = zipWith mkTest ['a'..] [myLast, myLast'] 
    where mkTest letter func = ('1':[letter], quickCheck $ prop_1 func)