Search code examples
haskelltypeclassquickcheck

How to implement the Arbitrary instance for data type like this?


I am new to Haskell, I am trying to write a test case to prove the associative law for Semigroup typeclass.

The data type define as followed:

newtype Combine a b = Combine {unCombine :: (a -> b)}

The implementation of Semigroup as followed:

instance (Semigroup b) => Semigroup (Combine a b) where 
  (Combine f) <> (Combine g) = Combine (\x -> f x <> g x)

I already wrote a associative test function

assocTestFunc :: (Eq m, Semigroup m) => m -> m -> m -> Bool
assocTestFunc a b c = (a <> b) <> c == a <> (b <> c)

and also defined a type alias like this:

type CombineAssoc = Combine String Ordering -> Combine String Ordering -> Combine String Ordering -> Bool

So in my main function, I can test it like this:

  quickCheck (assocTestFunc :: CombineAssoc)

However I am having a hard time to implement the Arbitrary instance for the Combine a b data type. Thanks advance for any help.


Solution

  • You can exploit the predefined instance for functions.

    instance (CoArbitrary a, Arbitrary b) => Arbitrary(Combine a b) where
       arbitrary = Combine <$> arbitrary