Buscar..


Codificación y decodificación inteligentes usando genéricos

La forma más fácil y rápida de codificar un tipo de datos Haskell a JSON con Aeson es mediante el uso de genéricos.

{-# LANGUAGE DeriveGeneric #-}

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

Primero creamos un tipo de datos Persona:

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

Para utilizar la función de encode y decode del paquete Data.Aeson , necesitamos que Person una instancia de ToJSON y FromJSON . Dado que derivamos Generic for Person , podemos crear instancias vacías para estas clases. Las definiciones predeterminadas de los métodos se definen en términos de los métodos proporcionados por la clase de tipo Generic .

instance ToJSON Person
instance FromJSON Person

¡Hecho! Para mejorar la velocidad de codificación podemos cambiar ligeramente la instancia de ToJSON :

instance ToJSON Person where
    toEncoding = genericToEncoding defaultOptions

Ahora podemos usar la función de encode para convertir Person a un Bytestring (perezoso):

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

Y para decodificar solo podemos usar decode :

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


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

Una forma rápida de generar 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

Campos opcionales

A veces, queremos que algunos campos de la cadena JSON sean opcionales. Por ejemplo,

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

Esto se puede lograr por

import Data.Aeson.TH

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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow