[Haskell-beginners] Typeclass problems

Daniel Fischer daniel.is.fischer at web.de
Thu Feb 4 17:37:12 EST 2010


Am Donnerstag 04 Februar 2010 23:14:33 schrieb Patrick LeBoutillier:
> Hi all,
>
> I've written a small type class that is meant to behave a bit like Show:
>
> class Show a => Echo a where
>   echo :: a -> String
>   echoList :: [a] -> String
>   echoListSep :: a -> String
>
>   echo = show
>   echoListSep _ = " "
>
>   echoList [] = ""
>   echoList [x] = echo x
>   echoList (x:xs) = echo x ++ echoListSep x ++ echoList xs
>
>
> instance Echo Char where
>   echo c = [c]
>   echoListSep _ = ""
>
> instance Echo a => Echo [a] where
>   echo = echoList
>
> instance Echo Int where
> instance Echo Integer where
> instance Echo Double where
> instance Echo Float where
>
>
> gen = map (const 1)
>
> f xs = map echo $ gen xs
>
>
> However the code doesn't compile on the last line.
> But it does compile if I replace 'echo' with 'show'.
> What's missing to make my typeclass behave like Show and accept input
> of any type (besides all the missing instances...)?
> I looked at the code for Show but I didn't see anything that looked
> "magical"...

The "magic" is that Show is defined in the standard libraries.
Read http://haskell.org/onlinereport/decls.html#sect4.3.4
In particular, the last bullet point of

"In situations where an ambiguous type is discovered, an ambiguous type 
variable, v, is defaultable if:

    * v appears only in constraints of the form C v, where C is a class, 
and
    * at least one of these classes is a numeric class, (that is, Num or a 
subclass of Num), and
    * all of these classes are defined in the Prelude or a standard library 
(Figures 6.2--6.3, pages -- show the numeric classes, and Figure 6.1, page 
, shows the classes defined in the Prelude.) "


Now,

gen xs :: Num a => [a]

And you want to map echo over it, so we get the constraint
(Num a, Echo a).

Echo is not defined in the standard libraries, thus no defaulting takes 
place, you have to specify the type of 1 explicitly,

map echo (gen xs :: [Int])

should work.

In real programmes, the type is often deducible from the context, so you'll 
be bitten by the defaulting restrictions less often then than at the ghci 
prompt.

There's a proposal (or a couple) to change the defaulting rules in coming 
language standards, see e.g. http://hackage.haskell.org/trac/haskell-
prime/wiki/Defaulting


>
>
> Thanks,
>
> Patrick

HTH,
Daniel



More information about the Beginners mailing list