I was trying to write a program that checks whether a list is palindrome and returns Bool.
isPalindrome :: [a] -> Bool
isPalindrome [] = True
isPalindrome [x] = True
isPalindrome xs | (head xs) == (last xs) = isPalindrome (init(tail xs))
| otherwise = False
And I recieved an error message like this:
problem6.hs:4:19: error:
* No instance for (Eq a) arising from a use of `=='
Possible fix:
add (Eq a) to the context of
the type signature for:
isPalindrome :: forall a. [a] -> Bool
* In the expression: (head xs) == (last xs)
In a stmt of a pattern guard for
an equation for `isPalindrome':
(head xs) == (last xs)
In an equation for `isPalindrome':
isPalindrome xs
| (head xs) == (last xs) = isPalindrome (init (tail xs))
| otherwise = False
|
4 | isPalindrome xs | (head xs) == (last xs) = isPalindrome (init(tail xs))
| ^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
Because I am not very experienced, I don't understand a thing from error message. So I don't see where the mistake is in my code. Thanks for helping.
The problem is you need to constrain the polymorphic type a
. Right now, the compiler has no information about the type, so it can't even know if (==)
is defined for a
(this is where the No instance for (Eq a) arising from a use of ``=='
comes from. It is trying to infer an instance of Eq
for a
, but it is unable to. You need to help it along).
You should make the type:
isPalindrome :: (Eq a) => [a] -> Bool
Now you're telling it that isPalindrome
can only be given lists of things that are instances of Eq
.
It points out this piece because your are trying to compare two a
's for equality:
(head xs) == (last xs)
A little bit about the error message:
Possible fix:
add (Eq a) to the context of
the type signature for:
isPalindrome :: forall a. [a] -> Bool
The stuff before the =>
in my suggestion is called the context, and it is where you can add constraints to your types. The suggestion here is telling you to do exactly what I said above (albeit in a much more verbose way).