You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Aeson解析异构数组字段返回Nothing问题及解决问询

解决Aeson解析异构JSON列表的问题

首先,咱们来拆解你遇到的问题:你的JSON里path是个异构数组——既有字符串(比如"networking"、"eth0"),又有数字(0),而你之前的代码里直接用fmap (V.! 2) (o .: "path"),这里o .: "path"会默认尝试把整个数组解析成Vector Text,但数组里的数字元素和Text类型不匹配,导致解析失败,最终返回Nothing。eitherDecode给出的报错expected Text, encountered Number也正好印证了这一点。

解决方案:把异构数组解析成Vector Value再处理

Aeson完全支持处理异构列表,核心思路是先把数组解析成保留所有原始类型的Vector Value(Aeson的Value类型可以表示任何JSON值),然后针对你需要的元素单独做类型转换。

修改你的FromJSON实例代码如下:

{-# 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) = do
        hniHost <- o .: "certname"
        -- 先把path解析成保留原始类型的Vector Value
        pathArr <- o .: "path"
        -- 取出索引为2的元素(也就是第3个元素),并转换为Text
        hniNic <- case pathArr V.!? 2 of
            Just val -> parseJSON val  -- 用parseJSON把Value转换成Text
            Nothing -> mzero  -- 如果数组长度不够,解析失败
        hniIp <- o .: "value"
        return HostNicIp{..}
    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\"}"

代码说明

  1. 解析path为Vector Value:o .: "path"在这里会返回Parser (Vector Value),因为Aeson无法推断出统一的元素类型,会默认保留每个元素的原始Value类型(字符串是String,数字是Number)。
  2. 安全取出目标元素:用V.!?代替V.!可以避免数组越界导致的运行时错误,如果索引不存在就返回mzero让解析失败。
  3. 类型转换:用parseJSON val把取出的Value转换成Text——因为你要的第3个元素是字符串,这个转换会成功;如果是数字元素,你可以用parseJSON val :: Parser Int来转换成整数类型。

验证结果

现在运行eitherDecode demo :: Either String HostNicIp,会得到:

Right (HostNicIp {hniHost = "some.server.name", hniNic = "eth0", hniIp = "192.168.1.1"})

这样就成功解决了异构数组的解析问题啦!

内容的提问来源于stack exchange,提问作者bongsun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:08:57