The simple and H98 solution here is to give your typeclass a toSexpList method and a fromSexpList method of [a] -> Sexp and Sexp - > Maybe [a] . The default implementation of this method is as in your instance for lists. For chars, you simply override this method to handle lists of chars differently. See the show and showList methods of the Show typeclass for an example of how this is done in the standard libraries.

--S

On Jan 18, 2009, at 2:23 PM, Brian Hurt wrote:


So, I'm working with this simplistic S-expression library of my own design (yes, I know, reinventing the wheel). Basically, I have the type:

data Sexp =
        List of [ Sexp ]
        | Atom of String

with the associated parsers and printers which really aren't relevent to the question at hand. Then, I want to define the type class of types I can convert to and from s-expressions, like:

class Sexpable a where
        toSexp :: a -> Sexp
        fromSexp :: Sexp -> Maybe a

here, fromSexp can return Nothing is the s-expression isn't the right form to be parsed into a whatever.

Now, here's the problem. I want to define a bunch of default instances, and two in particular I want to define are:

instance Sexpable String where
        toSexp s = Atom s
        fromSexp (Atom s) = Just s
        fromSexp _ = Nothing

instance Sexpable a => Sexpable [ a ] where
        toSexp lst = List $ map toSexp lst
        fromSexp (List lst) = mapM fromSexp lst
        fromSexp _ = Nothing

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].

There are two solutions to this that I already know of. One is to play games with newtype, which I don't like because it simply adds complexity in my case and doesn't help anything else. The second possibility is to compile with -fallow-incoherent-instances, which I'm slightly afraid of because I'm not sure what (if any) possible errors adding this option might allow.

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?

Thanks.

Brian

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to