[clean-list] New Clean Programmer
Diederik van Arkel
dvanarkel@mac.com
Tue, 28 Jan 2003 23:53:52 +0100
On Tuesday, January 28, 2003, at 07:24 PM, John M. Gogolin wrote:
> Hi folks,
>
> As is going to become painfully evident shortly, I'm rather new to the
> language of Clean.
>
> I've been trying to run through the exercises at the ends of the
> chapters in The Clean Book with mixed results. The one I'm currently
> working on is the second from chapter 3, which states:
>
> Define the function MakeFrequenceTable
> MakeFrequenceTable [a] -> [(a, Int)] | == a
>
> That makes a frequence table. The table consists of a list of
> tuples. Each tuple consists
> of an element from the original list and its frequency
> (percentage).
> E.g.
> Frequentietabel [1,2,3,2] = [(1,25),(2,50),(3,25)]
>
> Where I run into to trouble is the "| == a" clause. I can define the
> function as:
>
> MakeFrequenceTable :: [a] -> [(a, Int)] | Eq a
> MakeFrequenceTable [] = []
> MakeFrequenceTable [x:xs] = take n (removeDup([(x, Frequence x
> [x:xs])] ++ MakeFrequenceTable (xs ++ [x])))
> where n = length (removeDup [x:xs])
>
> with the support functions:
>
> CountOccurences :: a [a] -> Int | == a
> CountOccurences f [] = 0
> CountOccurences f [x:xs]
> | f == x = 1 + (CountOccurences f xs)
> = CountOccurences f xs
>
> Frequence :: a [a] -> Int | Eq a
> Frequence f x = 100 * (CountOccurences f x) / length x
>
> If I try to use "| == a", however, the compiler generates the error
> "internal overloading of "removeDup" could not be solved.
>
> After digging around some, I came up with a much shorter example that
> generates the same error:
>
> ShortenedList :: [a] -> [a] | == a
> ShortenedList list = removeDup list
>
> How is "| == a" in conflict with "| Eq a" in these cases? What
> fundamental piece am I not getting? Any help here would be greatly
> appreciated. Also, given that difference, how would one suggest
> writing
> the MakeFrequenceTable function as per requested in the text without
> rewriting a bunch of the library code?
>
> Thanks in advance,
> John
>
Hi John,
this is a rather poor error message by the compiler. What it's trying to
tell you is that '== a' which you provide in your function type isn't
enough to satisfy 'Eq a' required by removeDup. If you insist on having
this solution and still satisfying the '== a' restriction given in the
original problem you could copy the definition of removeDup from StdList
and change the '<>' which leads to the 'Eq a' requirement into 'notEq'
where
you define notEq a b = not (a == b), this allows you to change the class
restriction for both removeDup and MakeFrequenceTable to '== a'.
Regards,
Diederik van Arkel
P.S.
FrequenceTable l = frequencyTable (length l) l
frequencyTable n [] = []
frequencyTable n [x:xs] = [(x,length same + 1) : frequencyTable n diff]
where
same = [e \\ e <- xs | e == x]
diff = [e \\ e <- xs | not (e == x)]
freq = 100 * (length same + 1) / n
(programmed in Mail, may contain errors)