
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