How do I test this applicative instance with checkers? (No instance for CoArbitrary (Validation e0 [Char]))

Viewed 1126

Checkers is a library for reusable QuickCheck properties, particularly for standard type classes

How do I write a checkers instance to test whether my applicative instance of Validation is valid?

import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes
import Control.Applicative
import Data.Monoid

data Validation e a =
  Error e
  | Scss a
  deriving (Eq, Show)

instance Functor (Validation e) where
  fmap _ (Error e) = Error e
  fmap f (Scss a) = Scss $ f a

instance Monoid e => Applicative (Validation e) where
  pure = Scss
  (<*>) (Scss f) (Scss a) = Scss $ f a
  (<*>) (Error g) (Scss a) = Error g
  (<*>) (Scss a) (Error g) = Error g
  (<*>) (Error a) (Error g) = Error $ mappend a g

instance (Arbitrary a, Arbitrary b) => Arbitrary (Validation a b) where
  arbitrary = do
    a <- arbitrary
    b <- arbitrary
    elements [Scss a, Error b]

instance (Eq a, Eq b) => EqProp (Validation a b) where (=-=) = eq

main :: IO ()
main = quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]

I think I am almost there, but I get an error like:

chap17/Validation_applicative.hs:36:21: No instance for (CoArbitrary (Validation e0 [Char])) …
      arising from a use of ‘applicative’
    In the second argument of ‘($)’, namely
      ‘applicative [(Scss "b", Scss "a", Scss "c")]’
    In the expression:
      quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
    In an equation for ‘main’:
        main = quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
Compilation failed.

I have tried adding a CoArbitrary instance for Validation like so:

instance CoArbitrary (Validation a b)

but this leads to this error message:

chap17/Validation_applicative.hs:35:10: No instance for (GHC.Generics.Generic (Validation a b)) …
      arising from a use of ‘Test.QuickCheck.Arbitrary.$gdmcoarbitrary’
    In the expression: Test.QuickCheck.Arbitrary.$gdmcoarbitrary
    In an equation for ‘coarbitrary’:
        coarbitrary = Test.QuickCheck.Arbitrary.$gdmcoarbitrary
    In the instance declaration for ‘CoArbitrary (Validation a b)’
chap17/Validation_applicative.hs:38:21: No instance for (Eq e0) arising from a use of ‘applicative’ …
    The type variable ‘e0’ is ambiguous
    Note: there are several potential instances:
      instance Eq a => Eq (Const a b) -- Defined in ‘Control.Applicative’
      instance Eq a => Eq (ZipList a) -- Defined in ‘Control.Applicative’
      instance Eq a => Eq (Data.Complex.Complex a)
        -- Defined in ‘Data.Complex’
      ...plus 65 others
    In the second argument of ‘($)’, namely
      ‘applicative [(Scss "b", Scss "a", Scss "c")]’
    In the expression:
      quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
    In an equation for ‘main’:
        main = quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
Compilation failed.
1 Answers
Related