私は Haskell を初めて使用し、命令型プログラミングのバックグラウンドを持っています。「Haskell の方法」でオブジェクトを JSON にシリアル化できるようにしたいのですが、その方法はまだよくわかりません。
JSON について少し説明しているRealWorldHaskell の第 5 章を読み、Aeson をいじりました。また、次のような Haskell で記述されたいくつかの JSON API ライブラリも調べました。
これにより、オブジェクトから非常に基本的な JSON 文字列を作成できるようになりました (このブログ投稿のおかげでもあります)。
{-# 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 "foo@example.com" "Hello World"
let json = encode user
putStrLn $ show json
それは印刷されます:
"{\"email\":\"foo@example.com",\"name\":\"Hello World\"}"
ここでの目標は、User
任意のフィールドを持つことができるインスタンスに別のフィールドを追加することです。Facebook Graph API には、data
必要なプロパティを持つ JSON オブジェクトである というフィールドがあります。たとえば、Facebook の API に対して次のようなリクエストを行うことができます (疑似コード、Facebook API に正確には詳しくありません)。
POST api.facebook.com/actions
{
"name": "read",
"object": "book",
"data": {
"favoriteChapter": 10,
"hardcover": true
}
}
最初の 2 つのフィールドname
とobject
は typeString
ですが、data
フィールドは任意のプロパティのマップです。
User
問題は、上記のモデルでそれを達成するための「Haskell の方法」は何ですか?
単純なケースを行う方法を理解できます:
data User = User {
email :: String,
name :: String,
data :: CustomData
} deriving (Show, Generic)
data CustomData = CustomData {
favoriteColor :: String
}
しかし、それは私が探しているものではありません。つまり、User
JSON にシリアライズされると、型は常に次のようになります。
{
"email": "",
"name": "",
"data": {
"favoriteColor": ""
}
}
User
問題は、その型を 1 回定義するだけで、そのプロパティに任意のフィールドをアタッチできるようにするにはどうすればよいかということですdata
。その一方で、静的型付け (またはそれに近いもので、詳細にあまり精通していないもの) の恩恵を受けます。タイプのまだ)。