Suche…


Intelligente Kodierung und Dekodierung mit Generics

Die einfachste und schnellste Möglichkeit, einen Haskell-Datentyp in JSON mit Aeson zu codieren, ist die Verwendung von Generics.

{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics
import Data.Text
import Data.Aeson
import Data.ByteString.Lazy    

Zuerst erstellen wir einen Datentyp Person:

data Person = Person { firstName :: Text
                     , lastName  :: Text
                     , age       :: Int 
                     } deriving (Show, Generic)

Um die encode und decode aus dem Data.Aeson Paket verwenden zu können, müssen Sie Person als Instanz von ToJSON und FromJSON . Da wir Generic for Person ableiten, können wir für diese Klassen leere Instanzen erstellen. Die Standarddefinitionen der Methoden werden anhand der von der Generic Typklasse bereitgestellten Methoden definiert.

instance ToJSON Person
instance FromJSON Person

Erledigt! Um die Codierungsgeschwindigkeit zu verbessern, können wir die ToJSON Instanz leicht ändern:

instance ToJSON Person where
    toEncoding = genericToEncoding defaultOptions

Jetzt können wir die encode Funktion verwenden, um Person in einen (faulen) Bytestring umzuwandeln:

encodeNewPerson :: Text -> Text -> Int -> ByteString
encodeNewPerson first last age = encode $ Person first last age

Und zum Decodieren können wir einfach decode :

> encodeNewPerson "Hans" "Wurst" 30
"{\"lastName\":\"Wurst\",\"age\":30,\"firstName\":\"Hans\"}"


> decode $ encodeNewPerson "Hans" "Wurst" 30
Just (Person {firstName = "Hans", lastName = "Wurst", age = 30})

Eine schnelle Methode zum Generieren eines 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

Optionale Felder

Manchmal möchten wir, dass einige Felder in der JSON-Zeichenfolge optional sind. Zum Beispiel,

data Person = Person { firstName :: Text
                     , lastName  :: Text
                     , age       :: Maybe Int 
                     }

Dies kann durch erreicht werden

import Data.Aeson.TH

$(deriveJSON defaultOptions{omitNothingFields = True} ''Person)


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow