Skip to content

generic combinators backward compatibility issue #961

@rpeszek

Description

@rpeszek

IMO is not ideal and makes me question my use of generic combinators in Aeson.
At minimum, this should be documented as a gotcha.

Tested with aeson 1.5.6.0

Start like this

data FooBar = 
    Foo
    | Bar 
    deriving Generic

Things work as expected

import qualified Data.Aeson as A
>>> A.genericToJSON A.defaultOptions Foo 
String "Foo" 

New functionality is requested, new constructor is added, and FooBar becomes

data FooBar = 
    Foo
    | Bar 
    | Baz Int
    deriving Generic
>>> A.genericToJSON A.defaultOptions Foo 
Object (fromList [("tag",String "Foo")])

That IMO is concerning, that breaks compatibility. Adding a new constructor has changed how my old constructors are ToJSON and FromJSON-ed.

There is more (and is possibly related). One would expect allNullaryToStringTag to force the previous behavior (ideally I would not want to do that but let me try)

A.genericToJSON (A.defaultOptions {A.allNullaryToStringTag=True}) Foo
Object (fromList [("tag",String "Foo")])

Nope, what works is:

A.genericToJSON (A.defaultOptions {A.sumEncoding = A.UntaggedValue}) Foo
String "Foo"

Except this will drop tag in the Baz constructor too.
Maybe this has been fixed in newer versions? I could not find a ticket related to this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions