Aeson Parser为Array字段返回'Nothing'

时间:2018-01-23 10:05:36

标签: haskell aeson

我正在尝试从以下JSON输入中提取'path'键的第3个元素:

<dom-bind>

但是我在运行这个程序时得到的是“Nothing”:

{
  "certname": "some.server.name",
  "path": [
    "networking",
    "interfaces",
    "eth0",
    "bindings",
    0,
    "address"
  ],
  "name": "networking",
  "value": "192.168.1.1",
  "environment": "develop"
}

评论{-# LANGUAGE OverloadedStrings #-} import Control.Monad (mzero) import Data.Aeson import Data.ByteString.Lazy (ByteString) import Data.Text import qualified Data.Vector as V data HostNicIp = HostNicIp { hniHost :: !Text , hniNic :: !Text , hniIp :: !Text } deriving Show instance FromJSON HostNicIp where parseJSON (Object o) = HostNicIp <$> (o .: "certname") <*> fmap (V.! 2) (o .: "path") <*> (o .: "value" ) parseJSON _ = mzero main :: IO () main = print ( decode demo :: Maybe HostNicIp ) demo :: ByteString demo = "{\"certname\":\"some.server.name\",\"path\":[\"networking\",\"interfaces\",\"eth0\",\"bindings\",0,\"address\"],\"name\":\"networking\",\"value\":\"192.168.1.1\",\"environment\":\"develop\"}" 及其相关逻辑使程序解析其他所有内容

修改

使用hniNic运行此操作会让人抱怨遇到eitherDecode而不是Number

Text

虽然原始*Main> eitherDecode demo :: Either String HostNicIp Left "Error in $.path[4]: expected Text, encountered Number" 似乎已解析好了

Object

是否可以将Aeson用于异构列表?我该怎么做呢?

1 个答案:

答案 0 :(得分:3)

fmap (V.! 2) (o .: "path")

o .: "path"此处必须包含Parser (Vector Text)类型,但您提供的数组中包含数字。

相反,不要对数组进行解码,即在类型o .: "path"处使用Parser Value,然后通过模式匹配或使用withArray显式地破坏该值。然后给出一个Array(即,Vector Value,这是异构的)你可以获得第二个元素(V.! 2)并将其转换为Text(通过模式匹配,{{1} },或withText)。

parseJSON