
2013/7/23 Gesh hseG
The inference works somewhat like this: GHC sees the definitions of firstHalf, secondHalf and infers they have the same type as xs, and that all three of them must be some lists for them to be passed to and be returned by take and drop. GHC sees firstHalf == secondHalf. Since (==) has type Eq a => a -> a -> Bool, firstHalf (and secondHalf and xs) must have types which are instances of the typeclass Eq. Looking at the instance declarations for Eq, we find that for all types t which are instances of Eq, the type [t] (lists of values of type t) is also an instance of Eq. In other words, instance Eq a => Eq [a] where ...
Thus, we have that firstHalf, secondHalf, xs :: Eq t => [t] and cannot infer a more specific type for these three names, leaving us with the signature Eq t => [t] -> Bool for isPalindrome.
Intuitively, since you're checking whether the first half of the list is equal to the second half, you need to be able to check that the first element is equal to the last, second to the before-last, etc.
great post, thanks!
Also, notice that you could just have written isPalindrome xs = xs == reverse xs
Why didn't I think of that!? glg