[Haskell-cafe] Stupid question, re: overloaded type classes
Ryan Ingram
ryani.spam at gmail.com
Sun Jan 18 15:44:02 EST 2009
On Sun, Jan 18, 2009 at 11:23 AM, Brian Hurt <bhurt at spnz.org> wrote:
> instance Sexpable String where
> instance Sexpable a => Sexpable [ a ] where
> Note that I am not implementing Sexpable Char anywhere, so the only valid
> transform for [Char] should be the String one. But this still causes a
> compiler error due to the overloaded instances on [Char].
> So my question is twofold: 1) what errors might be allowed if I add
> -fallow-incoherent-instances, and 2) is there some third choice that avoids
> both solutions I already know about?
1) Incoherent instances end up being used in code like this:
blah :: Sexpable a => a -> Sexp
blah x = toSexp [x]
In this case, assuming an instance for Sexpable Char, this code may or
may not use the "wrong" instance, depending on what happens with
inlining:
blah 'x'
which passes the dictionary for Sexpable Char and then probably uses
the instance Sexpable a => Sexpable [a] (with a = Char), instead of
Sexpable String.
As long as there are no instances for Sexpable Char anywhere,
incoherent instances won't cause an error in this case. That said,
you can't guarantee that someone won't go and add an instance for
Char.
2) A third choice is to do what Show does, which is kind of a hack but
solves this specific problem:
class Sexpable a where
toSexp :: a -> Sexp
fromSexp :: Sexp -> Maybe a
toSexpList :: [a] -> Sexp
fromSexpList :: Sexp -> Maybe [a]
toSexpList = List . map toSexp
fromSexpList (List lst) = mapM fromSexp lst
fromSexpList _ = Nothing
instance Sexpable a => Sexpable [a] where
toSexp = toSexpList -- from Sexpable a, not [a]
fromSexp = fromSexpList
This requires Sexpable Char, though, to give you the right place to
put the instance. But it seems easy enough to include those; is there
a reason you explicitly don't want an instance for Char?
instance Sexpable Char where
toSexp c = toSexpList [c]
fromSexp l = do
[c] <- fromSexp l
return c
toSexpList s = Atom s
fromSexpList (Atom s) = Just s
fromSexpList _ = Nothing
I think that a design for typeclasses that eliminates the need for the
"showList" hack would be quite welcome.
-- ryan
More information about the Haskell-Cafe
mailing list