Reputation: 33
I have written the code below to test whether a list is a Palindrome or not. To my surprise its not compiling with the error "No instance for (Eq a) arising from a use of == ....". My assumption is that the compiler does not know that leftHalf
and rightHalf
are lists.
isPalindrome :: [a] -> Bool
isPalindrome [] = False
isPalindrome xs = if (leftHalf == reverse rightHalf)
then True
else False
where leftHalf = take center xs
rightHalf = drop center xs
center = if even (length xs)
then (length xs) `div` 2
else ((length xs) - 1) `div` 2
1) How do I tell the compiler that leftHalf
and rightHalf
are lists?
2) How would I use pattern matching or other haskell language features to solve this?
EDIT: Thank you all for your input. Special mention to Matt Fenwick for the documentation link and Duri for the elegant tip. I will write the final solutions below just in case
isPalindrome' :: (Eq a) => [a] -> Bool
isPalindrome' [] = False
isPalindrome' xs = if p then True else False
where p = leftHalf == rightHalf
leftHalf = take c xs
rightHalf = take c (reverse xs)
c = div l 2
l = length xs
isPalindrome'
can be improved like Demi pointed out
isPalindrome'' :: (Eq a) => [a] -> Bool
isPalindrome'' [] = False
isPalindrome'' xs = if (reverse xs) == xs then True else False
Upvotes: 3
Views: 185
Reputation: 5504
You should change your type to:
isPalindrome :: Eq a => [a] -> Bool
And this is really extraneous to find center, it's enough to just write xs == reverse xs
- when you computing length xs
you go through all the list and there is no economy.
Upvotes: 1
Reputation: 49095
Check out the Eq
typeclass:
ghci> :i (==)
class Eq a where
(==) :: a -> a -> Bool
...
-- Defined in GHC.Classes
infix 4 ==
What you need is a type constraint on isPalindrome
.
Also, this code
if (leftHalf == reverse rightHalf)
then True
else False
is unnecessarily long.
Upvotes: 2
Reputation: 12749
In order to test if two lists are equal, it must be possible to test if the items in the list are equal. Therefore, your list of type [a]
must ensure that a
is an instance of Eq
.
Also, as a matter of style:
x = if c then True else False
can be replaced with
x = c
Upvotes: 4