I'm trying to write the following test for an implementation of the dyadic rational numbers.
import Numeric.Natural
import Test.Hspec
import Test.Hspec.QuickCheck
import Dyadics
dyadic_add :: Integer -> Natural -> Integer -> Natural -> Bool
dyadic_add n1 p1 n2 p2 =
dyadic_to_rational (d1 `plus` d2) == (dyadic_to_rational d1) (dyadic_to_rational d2) where
d1 = Dyadic n1 p1
d2 = Dyadic n2 p2
main :: IO ()
main = hspec $ do
describe "Dyadic properties" $ do
prop "dyadics add like rationals" $ dyadic_add
I'm pretty new to haskell, so I only barely understand what I'm doing here.
I first wrote the test with this signature; dyadic_add :: Dyadic -> Dyadic -> Bool
.
Given that my data type is just data Dyadic = Dyadic Integer Natural
, I assumed that generating random Dyadics was a thing that QuickCheck could figure out how to do, but apparently not -- I got the error No instance for Test.QuickCheck.Arbitrary.Arbitrary Dyadic arising from a use of ‘prop’
.
I figured out that this means I need to implement Dyadics as an instance of Arbitrary
(just like how one would for Show
and Eq
). I maybe figured out how to do that, but it seemed messy and didn't quite work, and then I realized I could rewrite the test to take in Integer
s and Natural
s instead.
But then, I got the same error message for Natural
; No instance for (QuickCheck-2.14.2:Test.QuickCheck.Arbitrary.Arbitrary Natural) arising from a use of ‘prop’
.
This was very surprising to me -- does QuickCheck really not know how to generate an arbitrary Natural
? I think I can maybe figure out how to do that, but I get the feeling that there're lots of pre-existing functions inside QuickCheck that I should maybe be using instead, and also I'm running up against my ability to parse Haskell when trying to read QuickCheck example code. What's the best/simplest/most haskell-idiomatic way to do this?
CodePudding user response:
A bunch of these types are implemented in the package quickcheck-instances. Just add that into your dependencies, import Test.QuickCheck.Instances.Natural
, and you should be good to go!