-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Description
Sums of records are (de)serialized the same by aeson and this library:
:set -XDeriveGeneric
:set -XDeriveAnyClass
> import Data.Aeson (ToJSON, encode)
> import GHC.Generics (Generic)
> data A = A deriving (Generic, ToJSON)
> data B = B deriving (Generic, ToJSON)
> data D = C1 { f :: A } | C2 { g :: B } deriving (Generic, ToJSON)
> encode $ C1 A
"{\"tag\":\"C1\",\"f\":[]}"> import Data.Generic.Rep (class Generic)
> import Data.Argonaut (class EncodeJson, encodeJson, stringify)
> import Data.Argonaut.Aeson.Encode.Generic (genericEncodeAeson)
> import Data.Argonaut.Aeson.Options (defaultOptions)
> data A = A
> data B = B
> data D = C1 { f :: A } | C2 { g :: B }
> :paste
… derive instance genericA :: Generic A _
… instance encodeJsonA :: EncodeJson A where
… encodeJson = genericEncodeAeson defaultOptions
… derive instance genericB :: Generic B _
… instance encodeJsonB :: EncodeJson B where
… encodeJson = genericEncodeAeson defaultOptions
… derive instance genericD :: Generic D _
… instance encodeJsonD :: EncodeJson D where
… encodeJson = genericEncodeAeson defaultOptions
… ^D
> stringify $ encodeJson $ C1 { f: A }
"{\"f\":[],\"tag\":\"C1\"}"but while such data types are perfectly fine in PureScript they are unsafe in Haskell since the declaration of D yields f :: D -> A and g :: D -> B, which are partial.
This can be worked around by wrapping the fields of each constructor in their own type:
data C1Contents = C1Contents { f :: A } deriving (Generic, ToJSON)
data C2Contents = C2Contents { g :: B } deriving (Generic, ToJSON)
data D' = C1' C1Contents | C2' C2Contents deriving (Generic, ToJSON)but this changes the encoding:
> encode $ C1' $ C1Contents A
"{\"tag\":\"C1'\",\"contents\":{\"f\":[]}}"I’m aware that we can recover the same encoding in PureScript with newtypes, but would you be open to add to Data.Argonaut.Aeson.Options.SumEncoding a boolean option governing this behaviour?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels