0
votes

Currently, I am writing a function in Haskell to check a list is symmetric or not.

isReflexive :: Eq a => [(a, a)] -> Bool 
isReflexive [] = True
isReflexive xs = and [elem (x, x) xs | x <- [fst u | u <- xs] ++ [snd u | u <- xs]]

test = do
    print(isReflexive [])

main = test

The function works fine on the list that is not empty. However, when I test the empty list with the function, it raised an error

Ambiguous type variable ‘a2’ arising from a use of ‘isReflexive’ prevents the constraint ‘(Eq a2)’ from being solved.

Probable fix: use a type annotation to specify what ‘a2’ should be.

These potential instances exist:

instance Eq Ordering -- Defined in ‘GHC.Classes’

instance Eq Integer -- Defined in ‘integer-gmp-1.0.2.0:GHC.Integer.Type’

instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Maybe’ ...plus 22 others

...plus 7 instances involving out-of-scope types

(use -fprint-potential-instances to see them all)

• In the first argument of ‘print’, namely ‘(isReflexive [])’ How to fix this error?

1
Completely unrelated to your problem, only a style comment: consider pattern matching. I think and [elem (x, x) xs | (u, v) <- xs, x <- [u, v]] would be a particularly nice example of how to do that.Daniel Wagner

1 Answers

7
votes

The problem is simply that, in order to apply isReflexive, GHC needs to know which type you are using it on.

The type signature of isReflexive - Eq a => [(a, a)] -> Bool doesn't tell GHC a concrete type that the function works on. That's perfectly fine, and usual, but most often the code that calls the function makes it clear what exactly a is in that particular application. That's not so here, because [] has itself a polymorphic (and therefore ambiguous) type, [a] (for any a).

To fix it you simply have to provide a concrete type for your [] here, which is consistent with the signature of isReflexive. It really doesn't matter what, but an example from many that will work is:

test = do
    print(isReflexive ([] :: [(Int, Int)]))

(Note that this is exactly what GHC is telling you when it says Probable fix: use a type annotation to specify what 'a2' should be. 'a2' in that message corresponds to 'a' here, GHC tends to use 'a1', 'a2' etc to refer to all type variables.)