Ho passato un po 'di tempo a giocare con Aeson, ma non riesco a far serializzare correttamente i tipi di dati algebrici.Come serializzare gli ADT Haskell come ordinato JSON, usando Aeson?
Quello che ho provato è:
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)
l'output è:
{"tag":"AttachMsg","contents":{"tel":"+447890"}}
{"attach":{"tel":"+447890"},"fix":null}
L'uscita che sto cercando è:
{"attach":{"tel":"+447890"}}
ma dal tipo MsgIn
, piuttosto che MsgIn2
.
(L'uscita del MsgIn2
ottiene abbastanza vicino, ma ha un esplicito null
.)
C'è un modo di fare questo in Aeson?
Aggiornamento:
ho aggiunto:
instance ToJSON MsgIn3 where
toJSON (AttachMsg3 (Attach tel)) = object ["attach" .= object ["tel" .= tel]]
...
let reply3 = AttachMsg3 attach
BL.putStrLn (encode reply3)
ed ha ottenuto la risposta che volevo: {"attach":{"tel":"+447890"}}
.
@bheklilr esiste un modo per utilizzare la serializzazione di Attach (già definita), invece di definirla di nuovo?
ho provato un po 'di sintassi sciocchezza, ma comprensibilmente non si compila:
instance ToJSON MsgIn3 where
toJSON (AttachMsg3 (Attach tel)) = object ["attach" .= (toJSON :: Attach)]
È possibile scrivere manualmente le istanze 'ToJSON' e' FromJSON' per ottenere esattamente ciò che si desidera: 'toJSON (AttachMsg (Attach tel)) = oggetto [" attach ". = Object [" tel ". = Tel] ] ', e allo stesso modo per' FixMsg'. L'implementazione di 'parseJSON' non sarebbe molto più difficile. – bheklilr
@bheklilr Grazie, è stato davvero utile. Potresti farne una risposta?Potresti vedere la mia domanda aggiornata ... – fadedbee