AesonのFromJSON
関数を記述しようとしています。Aesonと入れ子になったJSONの解析配列
JSON:
{
"total": 1,
"movies": [
{
"id": "771315522",
"title": "Harry Potter and the Philosophers Stone (Wizard's Collection)",
"posters": {
"thumbnail": "http://content7.flixster.com/movie/11/16/66/11166609_mob.jpg",
"profile": "http://content7.flixster.com/movie/11/16/66/11166609_pro.jpg",
"detailed": "http://content7.flixster.com/movie/11/16/66/11166609_det.jpg",
"original": "http://content7.flixster.com/movie/11/16/66/11166609_ori.jpg"
}
}
]
}
ADT:data Movie = Movie {id::String, title::String}
私の試み:
instance FromJSON Movie where
parseJSON (Object o) = do
movies <- parseJSON =<< (o .: "movies") :: Parser Array
v <- head $ decode movies
return $ Movie <$>
(v .: "movies" >>= (.: "id")) <*>
(v .: "movies" >>= (.: "title"))
parseJSON _ = mzero
これはCouldn't match expected type 'Parser t0' with actual type 'Maybe a0' In the first argument of 'head'
を与えます。
ご覧のとおり、Array
の映画の最初を選んでいますが、映画のリストを取得しても構いません(複数の場合があります)。
ありがとうございます!私は別のタイプを導入することを考えなかった。迅速なフォローアップをお願いしますか? 'Movie'型を' filePath'や 'myRating'のようないくつかのフィールドを含むように拡張したいのであれば、新しい型の' myMovie'を追加するか、 'Movie'にいくつかの' Maybe'フィールドを導入することをお勧めしますタイプし、 'decode'の後にそれらを埋めますか? (私は、ADTは不変なので、実際にはすべてのフィールドで新しいインスタンスを作成することを意味すると思います。) – mb21
@ mb21:いずれの方法でもうまくいきます。それはあなたのアプリケーションの残りの部分に依存します。これらのフィールドがデコード直後に常に追加された場合、残りの関数が常に 'Just'であるべき' Maybe'を処理する必要がないように、新しい型を作ることは理にかなっているかもしれません。一方、これらのフィールドがオプションの場合は、それらを「未了」に保つことが理にかなっています。 – hammar
@ハマー:大丈夫、ありがとう! – mb21