问题
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:
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.)
来源:https://stackoverflow.com/questions/60243815/testing-empty-list-with-eq-type