I'm trying to use QuickCheck to test properties about length-indexed lists (a.k.a vectors) in Haskell. My trouble is that GHC is complaining about an ambiguous variable appearing on a Show constraint on main function.
I've defined vectors in a standard way
data Nat = Z | S Nat
data Vec :: Nat -> * -> * where
Nil :: Vec 'Z a
(:>) :: a -> Vec n a -> Vec ('S n) a
vlength :: Vec n a -> Int
vlength Nil = 0
vlength (_ :> xs) = 1 + vlength xs
and I have defined a function that converts it to a list
toList :: Vec n a -> [a]
toList Nil = []
toList (x :> xs) = x : (toList xs)
such conversion function should preserve length, that has an immediate encoding as a property:
toList_correct :: Show a => Vec n a -> Bool
toList_correct v = vlength v == length (toList v)
I've defined Arbitrary instances for Vec as:
instance (Show a, Arbitrary a) => Arbitrary (Vec 'Z a) where
arbitrary = return Nil
instance (Show a, Arbitrary a, Arbitrary (Vec n a)) => Arbitrary (Vec ('S n) a) where
arbitrary
= (:>) <$> arbitrary <*> arbitrary
The trouble happens when I call the quickCheck function on main:
main :: IO ()
main = quickCheck toList_correct
and GHC gives me the following message:
Ambiguous type variable ‘a0’ arising from a use of ‘quickCheck’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance [safe] Show Args -- Defined in ‘Test.QuickCheck.Test’
instance [safe] Show Result -- Defined in ‘Test.QuickCheck.Test’
instance (Show a, Show b) => Show (Either a b)
-- Defined in ‘Data.Either’
...plus 27 others
...plus 65 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: quickCheck toList_correct
In an equation for ‘main’: main = quickCheck toList_correct
I have no idea on how could I fix this error. Any tip is highly welcome.
The complete code is available here.