Haskell Language
Dati.Asone - JSON in Haskell
Ricerca…
Codifica e decodifica intelligenti con generici
Il modo più semplice e veloce per codificare un tipo di dati Haskell su JSON con Aeson è l'utilizzo di generici.
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
import Data.Text
import Data.Aeson
import Data.ByteString.Lazy
Per prima cosa creiamo un tipo di dati Persona:
data Person = Person { firstName :: Text
, lastName :: Text
, age :: Int
} deriving (Show, Generic)
Per utilizzare la funzione di encode
e decode
dal pacchetto Data.Aeson
, è necessario rendere a Person
un'istanza di ToJSON
e FromJSON
. Dal momento che deriviamo Generic
for Person
, possiamo creare istanze vuote per queste classi. Le definizioni predefinite dei metodi sono definite in termini di metodi forniti dalla classe di tipi Generic
.
instance ToJSON Person
instance FromJSON Person
Fatto! Per migliorare la velocità di codifica, possiamo modificare leggermente l'istanza ToJSON
:
instance ToJSON Person where
toEncoding = genericToEncoding defaultOptions
Ora possiamo usare la funzione di encode
per convertire la Person
in un Bytestring (pigro):
encodeNewPerson :: Text -> Text -> Int -> ByteString
encodeNewPerson first last age = encode $ Person first last age
E per decodificare possiamo semplicemente usare la decode
:
> encodeNewPerson "Hans" "Wurst" 30
"{\"lastName\":\"Wurst\",\"age\":30,\"firstName\":\"Hans\"}"
> decode $ encodeNewPerson "Hans" "Wurst" 30
Just (Person {firstName = "Hans", lastName = "Wurst", age = 30})
Un modo rapido per generare un Data.Aeson.Value
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Aeson
main :: IO ()
main = do
let example = Data.Aeson.object [ "key" .= (5 :: Integer), "somethingElse" .= (2 :: Integer) ] :: Value
print . encode $ example
Campi opzionali
A volte, vogliamo che alcuni campi nella stringa JSON siano facoltativi. Per esempio,
data Person = Person { firstName :: Text
, lastName :: Text
, age :: Maybe Int
}
Questo può essere raggiunto da
import Data.Aeson.TH
$(deriveJSON defaultOptions{omitNothingFields = True} ''Person)