Home > Software engineering >  No instance for (Arbitrary Natural) arising from a use of ‘prop’
No instance for (Arbitrary Natural) arising from a use of ‘prop’

Time:11-09

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 Integers and Naturals 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!

  • Related