Haskell Language
Data.Aeson - JSON в Хаскелле
Поиск…
Интеллектуальное кодирование и декодирование с использованием дженериков
Самый простой и быстрый способ кодирования типа данных Haskell для JSON с помощью Aeson использует дженерики.
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
import Data.Text
import Data.Aeson
import Data.ByteString.Lazy
Сначала создадим тип данных Person:
data Person = Person { firstName :: Text
, lastName :: Text
, age :: Int
} deriving (Show, Generic)
Чтобы использовать функцию encode
и decode
из пакета Data.Aeson
, нам нужно сделать Person
экземпляром ToJSON
и FromJSON
. Поскольку мы получаем Generic
для Person
, мы можем создавать пустые экземпляры для этих классов. Определения по умолчанию для методов определяются в терминах методов, предоставляемых классом типа Generic
.
instance ToJSON Person
instance FromJSON Person
Готово! Чтобы улучшить скорость кодирования, мы можем немного изменить экземпляр ToJSON
:
instance ToJSON Person where
toEncoding = genericToEncoding defaultOptions
Теперь мы можем использовать функцию encode
для преобразования Person
в (ленивый) Bytestring:
encodeNewPerson :: Text -> Text -> Int -> ByteString
encodeNewPerson first last age = encode $ Person first last age
И для декодирования мы можем просто использовать decode
:
> encodeNewPerson "Hans" "Wurst" 30
"{\"lastName\":\"Wurst\",\"age\":30,\"firstName\":\"Hans\"}"
> decode $ encodeNewPerson "Hans" "Wurst" 30
Just (Person {firstName = "Hans", lastName = "Wurst", age = 30})
Быстрый способ создания 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
Дополнительные поля
Иногда мы хотим, чтобы некоторые поля в строке JSON были необязательными. Например,
data Person = Person { firstName :: Text
, lastName :: Text
, age :: Maybe Int
}
Это может быть достигнуто
import Data.Aeson.TH
$(deriveJSON defaultOptions{omitNothingFields = True} ''Person)