<div dir="ltr">Hi Brian,<div><br></div><div>You could eliminate the JSON constructor from your servant types by using it in the aeson instance for Foo itself:<br></div><div><div><br></div><div><font face="monospace, monospace"> instance ToJSON Foo where</font></div><div><font face="monospace, monospace"> toJSON = toJSON . JSON</font></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> instance FromJSON Foo where</font></div><div><font face="monospace, monospace"> parseJSON = fmap (\(JSON t) -> t) . parseJSON</font></div><div><br></div><div>This way, JSON is used only where it's relevant: not in the servant types, but in the aeson instances. It gives the programmer a way to get them for HasStructParser types at pretty much no cost. I don't think duplicate instances are a concern here. If you want to use an existing aeson-equipped type in your servant routes, but redefine those aeson instance via HasStructParser, then make a newtype. In my opinion it's a good idea to have new types for servant inputs anyway, to make very clear the provenance of these values.</div><div><br></div><div>Alex</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, May 22, 2016 at 1:05 PM, Brian Hurt <span dir="ltr"><<a href="mailto:bhurt@spnz.org" target="_blank">bhurt@spnz.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div>This is driving me nuts.</div><div><br></div><div>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:</div><div> instance HasStructParser s => ToJSON s where</div><div> ...</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>I suppose I could go:</div><div><br></div><div> newtype JSON a = JSON a</div><div><br></div><div> instance HasStructParser s => ToJSON (JSON s) where ...</div><div><br></div><div>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:</div><div> :<|> "foo" :> "bar" :> Get '[JSON] [Foo]<br>I have to write:</div><div> :<|> "foo" :> "bar" :> Get '[JSON] [JSON Foo]<br><br></div><div>And, of course, if I want to have multiple different types of outputs, now we're off to the races.</div><div><br></div><div>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?</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Brian</div><div><br></div></font></span></div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br></div>