[Haskell-cafe] Going insane over overlapping instances

Brian Hurt bhurt at spnz.org
Sun May 22 17:05:52 UTC 2016

This is driving me nuts.

So I have a type class HasStructParser I've defined. Details are irrelevant
except that if you have HasStructParser defined, then ToJSON is also
defined.  So I have:
    instance HasStructParser s => ToJSON s where

But now, any type that defines ToJSON any other way causes an Overlapping
Instances error to happen- the conflict being between the real ToJSON
implementation and the one deriving from HasStructParser- this despite the
fact that there is no implementation for HasStructParser for the given type.

Now, I don't want to allow Overlapping Instances because if there are
*real* overlapping instances, I want that to be an error.  For instance, if
a structure did implement HasStructParser and some other implementation of
ToJSON, I want to know.

I suppose I could go:

    newtype JSON a = JSON a

    instance HasStructParser s => ToJSON (JSON s) where ...

But this strikes me as being ugly- now I have to add pointless JSON
constructors everywhere I want to convert to (or from) JSON.  And this also
pollutes my type signatures all over the place- now I can't write a servant
endpoint type like:
    :<|> "foo" :> "bar" :> Get '[JSON] [Foo]
I have to write:
    :<|> "foo" :> "bar" :> Get '[JSON] [JSON Foo]

And, of course, if I want to have multiple different types of outputs, now
we're off to the races.

So my question is, is there a way to do this without throwing the baby out
with the bath water (turning on overloaded instances) or being seriously
ugly?  Or am I just screwed?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20160522/ad6937bd/attachment.html>

More information about the Haskell-Cafe mailing list