Ich habe einige Zeit damit verbracht, mit Aeson herumzuspielen, aber ich kann Algebraische Datentypen nicht serialisieren.Wie man Haskell ADTs als ordentliches JSON mit Aeson serialisiert?
Was ich versucht habe, ist:
data Attach = Attach { tel :: String }
deriving (Show)
$(deriveJSON defaultOptions ''Attach)
data Fix = Fix { lat :: Double, lng :: Double }
deriving (Show)
$(deriveJSON defaultOptions ''Fix)
data MsgIn = AttachMsg Attach
| FixMsg Fix
deriving (Show)
$(deriveJSON defaultOptions ''MsgIn)
data MsgIn2 = MsgIn2 { attach :: Maybe Attach, fix :: Maybe Fix }
deriving (Show)
$(deriveJSON defaultOptions ''MsgIn2)
someFunc :: IO()
someFunc = do
let attach = Attach "+447890"
let reply = AttachMsg attach
BL.putStrLn (encode reply)
let reply2 = MsgIn2 (Just attach) Nothing
BL.putStrLn (encode reply2)
Die Ausgabe lautet:
{"tag":"AttachMsg","contents":{"tel":"+447890"}}
{"attach":{"tel":"+447890"},"fix":null}
Der Ausgang ich suche ist:
{"attach":{"tel":"+447890"}}
aber vom Typ MsgIn
, anstatt MsgIn2
.
(Die Ausgabe von MsgIn2
recht nahe kommt, aber es ist eine explizites null
bekommt.)
Gibt es eine Möglichkeit, dies in Aeson zu tun?
Update:
ich hinzugefügt:
instance ToJSON MsgIn3 where
toJSON (AttachMsg3 (Attach tel)) = object ["attach" .= object ["tel" .= tel]]
...
let reply3 = AttachMsg3 attach
BL.putStrLn (encode reply3)
und bekam die Antwort, die ich wollte: {"attach":{"tel":"+447890"}}
.
@bheklilr Gibt es eine Möglichkeit, die (bereits definierte) Serialisierung von Attach zu verwenden, anstatt sie erneut zu definieren?
Ich habe einige Unsinn Syntax versucht, aber verständlicherweise es nicht kompilieren:
instance ToJSON MsgIn3 where
toJSON (AttachMsg3 (Attach tel)) = object ["attach" .= (toJSON :: Attach)]
Sie könnten einfach die 'ToJSON'- und' FromJSON'-Instanzen manuell schreiben, um genau das zu bekommen, was Sie wollen: 'toJSON (AttachMsg (Attach tel)) = Objekt [" attach ". = Objekt [" tel ". = Tel] ] ', und ähnlich für' FixMsg'. Die 'parseJSON'-Implementierung wäre nicht viel schwieriger. – bheklilr
@bheklilr Danke, das war wirklich nützlich. Könnten Sie es zu einer Antwort machen?Könnten Sie meine aktualisierte Frage sehen? – fadedbee