haskell - 使用 Aeson 解析嵌套 JSON 中的数组

标签 haskell aeson

我正在尝试写一个 FromJSON Aeson 的功能。

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从电影的 JSON 数组中,您可以执行以下操作:

instance FromJSON Movie where
    parseJSON (Object o) = do
        movieValue <- head <$> o .: "movies"
        Movie <$> movieValue .: "id" <*> movieValue .: "title"
    parseJSON _ = mzero

但更安全的方法是解析 [Movie]通过 newtype包装:
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

关于haskell - 使用 Aeson 解析嵌套 JSON 中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16547783/

相关文章:

haskell - 使用 getLine 和 putStr 时发生 IO 乱序

algorithm - 线程二叉树结构在 Haskell 中有什么优势吗?

haskell - Aeson 中的单标签构造函数

haskell - 如何处理不完整的 JSON/Record 类型(IE 缺少我稍后会填写的必填字段)?

haskell - `sequence` 与 `ap` 的实现

Haskell - 语法错误

haskell - 使用 Aeson 读取对象的单个字段,无需编写 FromJSON 实例

haskell - Aeson 棱镜,引用号为 "free"

haskell - 列表的头部可以代表多个值吗

json - Haskell Servant 自定义 JSON 解析错误