
On Sun, Jan 18, 2009 at 11:23 AM, Brian Hurt
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