Anyone knows why the following code fails in " matchListWith eq [] []
"?
-- failure.hs
matchListWith :: (Eq a) => (a -> a -> Bool) -> [a] -> [a] -> Bool
matchListWith f (x:xs) (y:ys) = (f x y) && (matchListWith f xs ys)
matchListWith _ [] [] = True
matchListWith _ _ _ = False
eq :: (Eq a) => a -> a -> Bool
eq a b = (a == b)
main = do
print (matchListWith eq [1, 3] [1, 3])
print (matchListWith eq [1, 3] [1])
print (matchListWith eq [1] [1, 3])
print (matchListWith eq [3, 1] [1, 3])
print (matchListWith eq [1] [])
print (matchListWith eq [] [])
-- eof
The error is:
failure.hs:16:11:
No instance for (Eq a0) arising from a use of `matchListWith'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in `GHC.Real'
instance Eq () -- Defined in `GHC.Classes'
instance (Eq a, Eq b) => Eq (a, b) -- Defined in `GHC.Classes'
...plus 22 others
In the first argument of `print', namely `(matchListWith eq [] [])'
In a stmt of a 'do' block: print (matchListWith eq [] [])
In the expression:
do { print (matchListWith eq [1, 3] [1, 3]);
print (matchListWith eq [1, 3] [1]);
print (matchListWith eq [1] [1, 3]);
print (matchListWith eq [3, 1] [1, 3]);
.... }
The weird things is, if I load the two functions in GHCi, matchListWith eq [] []
, works just fine.
*Main> matchListWith eq [] []
True
*Main>
I'm using GHC version 7.6.3.
The reason is because when you call
matchListWith eq [] []
The compiler doesn't know what type of list it is. All it knows is that it's a value of type [a]
, but that does not put the Eq a =>
constraint on it. Change it to
matchListWith eq [] ([] :: [Int])
and it should compile
Sometimes you have to give GHC a bit of help to know what types it's working with. It would be the same if you tried
myFunc :: m Int
myFunc = do
let x = 1
y = 2
return $ x + y
This wouldn't compile because the compiler isn't told that m
is a Monad
, you have to add the extra context of
myFunc :: Monad m => m Int
for it to work.
The reason why it works in GHCi is because there's a bit more eager type inference. GHCi will often pick a more concrete type than GHC will in order to make the interactive part easier to use.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.