Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid creating an orphan FromJSON instance for Data.Tree

I'm using the aeson package. I have a datatype which uses Data.Tree in its declaration. Like the following, only more complex:

 data Foo = Foo {
               bat :: Text 
             , xux :: Maybe Text 
             , tri :: Tree Text
            }

I want to use Data.Aeson.TH to generate a FromJSON instance for this type.

$(deriveJSON defaultOptions ''Foo)

But Data.Tree does not have a standard instance for FromJSON, meaning that I would need to declare an orphan instace.

Is there some way to avoid creating that orphan instance, while still being able to use deriveJSON?

like image 864
danidiaz Avatar asked Oct 12 '13 16:10

danidiaz


1 Answers

In order for an instance to be canonical (i.e. not an orphan), it needs to be defined in the same module as either the type constructor (Data.Tree) or the class declaration (Data.Aeson.Types). So the only way to define a non-orphan instance would be to fork aeson (since aeson depends on containers).

I'd recommend filing a ticket with aeson, or possibly a pull request, to get it added upstream. Until then, if you don't plan to distribute the code, defining an orphan instance shouldn't cause much trouble. If you're working on code you want to publish, the safest solution is to create a newtype wrapper around Tree, then make a FromJSON instance for the newtype.

like image 142
John L Avatar answered Oct 13 '22 06:10

John L