我正在为Aeson写一个From
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
这给出了无法匹配预期类型’Parser t0’与实际类型’也许a0’在’头’的第一个参数.
正如你所看到的,我正在尝试选择Array中的第一部电影,但是我也不会介意获得电影列表(如果Array中有几个).
解决方法@H_502_18@
如果您真的想从JSON数组电影解析单个影片,您可以执行以下操作:
instance FromJSON Movie where
parseJSON (Object o) = do
movieValue <- head <$> o .: "movies"
Movie <$> movieValue .: "id" <*> movieValue .: "title"
parseJSON _ = mzero
但更安全的路线是通过newtype包装解析[Movie]:
main = print $movieList <$> decode "{\"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\"}}]}"
newtype MovieList = MovieList {movieList :: [Movie]}
instance FromJSON MovieList where
parseJSON (Object o) = MovieList <$> o .: "movies"
parseJSON _ = mzero
data Movie = Movie {id :: String,title :: String}
instance FromJSON Movie where
parseJSON (Object o) = Movie <$> o .: "id" <*> o .: "title"
parseJSON _ = mzero
instance FromJSON Movie where parseJSON (Object o) = do movieValue <- head <$> o .: "movies" Movie <$> movieValue .: "id" <*> movieValue .: "title" parseJSON _ = mzero
但更安全的路线是通过newtype包装解析[Movie]:
main = print $movieList <$> decode "{\"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\"}}]}" newtype MovieList = MovieList {movieList :: [Movie]} instance FromJSON MovieList where parseJSON (Object o) = MovieList <$> o .: "movies" parseJSON _ = mzero data Movie = Movie {id :: String,title :: String} instance FromJSON Movie where parseJSON (Object o) = Movie <$> o .: "id" <*> o .: "title" parseJSON _ = mzero