简体   繁体   中英

Haskell: No instance for (Eq a) arising from a use of `==' In the expression: (b == c)

So, im on my first steps on haskell, and i was asked on class to define the "elem" function. This was my first idea:

elemento :: a -> [a] -> Bool
elemento b listab = foldl (||) False (map (esIgual b) listab)

esIgual :: a -> a -> Bool
esIgual b c = (b == c)

Wich results in

elem (parcialito).hs:5:18: No instance for (Eq a) arising from a use of ==' In the expression: (b == c) In an equation for esIgual': esIgual bc = (b == c)

I think it´s something related to b and c not being recognized as a "Eq a" type or something like that, but as i said, im on baby steps here yet. Any ideas?

I won't get into an explanation of type classes (you should read some haskell tutorials to find out about that) but the basic idea is that, as you said, in order to use the function == on b and c , which are both of type a , you need some guarantee that there is an implementation of the == function for that type. In haskell we call that a "type constraint" and we write it as:

esIgual :: Eq a => a -> a -> Bool
esIgual b c = (b == c)

Note that you could have omitted the type annotation for esIgual and the compiler would have inferred it for you. Try to write only

esIgual b c = (b == c)

then load the file into GHCI and type:

:t esIgual

You will also need to add a constraint in elemento since it is using isIgual:

elemento :: Eq a => ...

Check this out: http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101 :) The first example is precisely about == .

esIgual currently promises to return a Bool for any two objects of the same type a , with no requirements at all on what type that is. But it uses == to do that, and == only works of a is an instance of Eq , the typeclass that lets you compare objects for equality. That requirement needs to be reflected in the type signature of esIgual , like:

esIgual :: Eq a => a -> a -> Bool

Then that needs to propagate out to elemento as well:

elemento :: Eq a => a -> [a] -> Bool

You need to declare esIgual to require arguments of types from the typeclass Eq :

esIgual :: Eq a => a -> a -> Bool
esIgual b c = (b == c)

Otherwise there's no way for Haskell to apply the == operator to the arbitrary type a .

(Or, as Aegis points out, just skip the declaration altogether)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM