Haskell Aeson Parse混合元素阵列

时间:2018-06-16 21:24:50

标签: json parsing haskell aeson

我有一个json喜欢:

{
  "name" : "Sam",
  "items": [ "sword", "shield", [] ]
}

和数据类型

data Adventurer = Adventurer {
  name :: String,
  items :: [String]
} deriving (Generic, Show, FromJSON, ToJSON)

问题是由于"项目"字段在数组中有额外的[],我得到"期望的字符串,遇到数组"。

我一直在尝试使用自定义数据类型来解决这个问题。" items"数组,或尝试使自定义解析器忽略额外的数组。

有没有办法解析一个数组,只采取某种类型的项目,其余部分丢弃?

1 个答案:

答案 0 :(得分:1)

是的,我们可以首先构建一个将Value s(这些是JSON对象)映射到Maybe String的函数:

import Data.Aeson(Value(String))
import Data.Text(unpack)

getString :: Value -> Maybe String
getString (String t) = Just (unpack t)
getString _ = Nothing

然后,我们可以为FromJOSN定义Adventurer的自定义实现,例如:

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson(FromJSON(parseJSON), withObject, (.:))
import Data.Maybe(catMaybes)

instance FromJSON Adventurer where
    parseJSON = withObject "Adventurer" $ \v -> Adventurer
        <$> v .: "name"
        <*> fmap (catMaybes . map getString) (v .: "items")

然后产生例如:

Main> t = "{\n  \"name\" : \"Sam\",\n  \"items\": [ \"sword\", \"shield\", [] ]\n}"
Main> decode t :: Maybe Adventurer 
Just (Adventurer {name = "Sam", items = ["sword","shield"]})