Я новичок в Haskell, исходя из императивного программирования. Я хотел бы иметь возможность сериализовать объект в JSON в «Haskell way», но не совсем уверен, как это сделать.Haskell-способ моделирования типа с динамическими полями JSON?
Я прочитал Chapter 5 of RealWorldHaskell, который немного говорит о JSON и играет с Aeson. Я также посмотрел на несколько API библиотек JSON, написанных на Haskell, такие как:
Это заставило меня к тому, чтобы быть в состоянии создать очень простые строки JSON из объекты (в том числе благодаря this blog post):
{-# LANGUAGE OverloadedStrings, DeriveGeneriC#-}
import Data.Aeson
import GHC.Generics
data User = User {
email :: String,
name :: String
} deriving (Show, Generic)
instance ToJSON User
main = do
let user = User "[email protected]" "Hello World"
let json = encode user
putStrLn $ show json
Это будет печатать:
"{\"email\":\"[email protected]",\"name\":\"Hello World\"}"
Теперь цель заключается в добавлении другого поля в экземпляр User
, который может иметь произвольные поля. API-интерфейс Facebook Graph имеет поле data
, которое представляет собой объект JSON с любым желаемым свойством. Например, вы можете делать запросы, как это в API Facebook, (псевдокод, не знакомы с API Facebook точно):
POST api.facebook.com/actions
{
"name": "read",
"object": "book",
"data": {
"favoriteChapter": 10,
"hardcover": true
}
}
Первые два поля, name
и object
являются тип String
, в то время как data
поле является отображение произвольных свойств.
Вопрос в том, что такое «путь Haskell», чтобы выполнить это на модели User
выше?
Я могу понять, как сделать простой случай:
data User = User {
email :: String,
name :: String,
data :: CustomData
} deriving (Show, Generic)
data CustomData = CustomData {
favoriteColor :: String
}
Но это не совсем то, что я ищу. Это означает, что тип User
, когда сериализуется в JSON, всегда будет выглядеть следующим образом:
{
"email": "",
"name": "",
"data": {
"favoriteColor": ""
}
}
Вопрос заключается в том, как сделать это так, вам нужно только определить, что User
типа один раз, а затем может иметь произвольные поля прикрепленный к этому свойству data
, при этом все еще пользуясь статической типизацией (или тем, что близко к ней, не слишком хорошо знакомы с деталями типов).
Вы хотите изучить «Может быть» и «Либо». –
См. Http://hackage.haskell.org/package/aeson-0.6.1.0/docs/Data-Aeson.html#g:8 (псевдоним 'Object') –
Невозможно также использовать статическое типирование с произвольными типами данных - как вы можете статически анализировать динамическое поле? Лучшее, на что вы можете надеяться, с «произвольными данными» - либо сбой, либо получить его правильно во время выполнения (например, через Либо и, может быть, и, возможно, это не произвольно) –