vwendy
vwendy

Reputation: 153

Problem with run-length encoding code

This was the #10 of the 99 Haskell questions:

(*) Run-length encoding of a list. Use the result of problem P09 to implement the so-called run-length encoding data compression method. Consecutive duplicates of elements are encoded as lists (N E) where N is the number of duplicates of the element E.

Example in Haskell: encode "aaaabccaadeeee" -> [(4,'a'),(1,'b'),(2,'c'),(2,'a'),(1,'d'),(4,'e')]

Here is my code:

import Data.List
encode :: [a] -> [(Int,a)]
encode = map (\ws -> (length ws, head ws)) . group

Here is the error I got:

No instance for (Eq a)
arising from a use of `group'
In the second argument of `(.)', namely `group'
In the expression: map (\ ws -> (length ws, head ws)) . group
In an equation for `encode':
    encode = map (\ ws -> (length ws, head ws)) . group

I don't understand what's wrong with the use of group, and if I change the type of function to String -> [(Int, Char)], it will run through.

How can I fix this?

Upvotes: 1

Views: 1311

Answers (1)

geekosaur
geekosaur

Reputation: 61369

To use the group function, you need to promise that you will pass a list of items on which == can be used, which is to say, members of the Eq typeclass. If you omit the type, or you specify a type which is a member of Eq, it will work; if you want to be more general, you need to promise it that you are using something that is in Eq:

encode :: Eq a => [a] -> [(Int,a)]
encode =  map (\ws -> (length ws, head ws)) . group

(In reality this is passing the implementation of Eq for a as a hidden parameter, so group will know which (==) to use; the similarity to function parameters is deliberate.)

Upvotes: 6

Related Questions