2013-04-24 21 views
5

Napisałem implementację dla foldl i chciałem sprawdzić, czy zadziałało, próbowałem niektórych przypadków i wygląda na to, że działa dobrze, ale chcę się upewnić.Użycie quickCheck

Czytałem o QuickCheck i próbował, ale nie wydaje się, aby działać, jest to kod

foldl'' :: (b -> a -> b) -> b -> [a] -> b 

test :: Eq b => (b -> a -> b) -> b -> [a] -> Bool 
test f e ls = foldl'' f e ls == foldl f e ls 

kiedy biegnę quickCheck test zgłasza następujący błąd:

No instance for (Show (b0 -> a0 -> b0)) 
    arising from a use of `quickCheck' 
Possible fix: 
    add an instance declaration for (Show (b0 -> a0 -> b0)) 
In the expression: quickCheck prueba 
In an equation for `it': it = quickCheck prueba 

Odpowiedz

7

Twoja własność wymaga trzech danych wejściowych: funkcji, elementu i listy. Problem polega na tym, że QuickCheck nie wie, jak radzić sobie z funkcjami w ogóle.

Jedną z rzeczy, którą QuickCheck musi zadziałać, jest możliwość zapisu na konsolę przypadków niepowodzenia testów. Do tego potrzebne są wartości, które może przekształcić w String - wszystko w klasie Show. Ponieważ funkcje nie są w Show, nie można ich użyć do wprowadzania danych. Stąd pochodzi komunikat o błędzie.

Generalnie, używanie losowo generowanych funkcji do testowania będzie dość trudne. Napisałem tylko kilka konkretnych funkcji i pozwoliłem QuickCheck losowo wygenerować wartość początkową i listę elementów.

2

Z tego co rozumiem, istnieje mechanizm do tworzenia losowych funkcji w QuickCheck (patrz Test.QuickCheck.Function), ale nie mogę powiedzieć, że znam to na tyle dobrze, aby powiedzieć ci, jak z niego korzystać.

To powiedziawszy, testowanie własności prawdopodobnie ma więcej sensu dzięki funkcjom, które sam wybierzesz, więc możesz napisać coś w stylu quickCheck $ prueba (+), które będzie działało dobrze.

6

Istnieje sposób na uniknięcie ograniczenia Show na wejściach za pomocą modyfikatora Blind, który umożliwi korzystanie z mechanizmów QuickCheck do generowania losowych funkcji.

-- Using Int instead of a, b which would be defaulted to() in GHCi 
prueba :: Blind (Int -> Int -> Int) -> Int -> [Int] -> Bool 
prueba (Blind f) e ls = foldl'' f e ls == foldl f e ls 

Powiedział, że oznacza to wyjście porażka jest prawie bezużyteczny do debugowania, jak to będzie po prostu wydrukować (*) dla wejścia w ciemno. (Dla wykazania, że ​​określono foldl'' = foldr . flip)

> quickCheck prueba 
*** Failed! Falsifiable (after 4 tests and 2 shrinks):  
(*) 
0 
[1,0] 
+0

Nie w zakresie: konstruktor typu lub klasy 'Blind” – chamini2

+0

@ chamini2: Czy importowany 'Test.QuickCheck'? – hammar

+0

tak, może dlatego, że jestem na OS X? 'Ghci --version: The Glorious Glasgow Haskell Compilation System, wersja 7.4.2' – chamini2