Haskell Aeson如何正确解析值为列表类型的JSON键?
问题原因
你在解析时强制将accounts字段的返回值声明为Object类型,但从提供的JSON结构可以看到,accounts对应的值是数组类型,Aeson中JSON对象对应Object类型,JSON数组对应Array类型(本质是Data.Vector的可变向量结构),类型不匹配导致解析失败返回Nothing。
而exchangeAgreements字段对应的值本身是JSON对象,和你声明的Object类型匹配,所以可以正常解析。
调整方案
方案1:直接获取原始JSON数组结构
如果你只需要拿到原始的JSON数组值,直接将类型声明改为Array即可:
fromJust (Data.Aeson.Types.parseMaybe (\o -> o .: ("accounts" :: Data.Text.Text)) myobject) :: Array
如果需要遍历数组内的对象,可以调用Data.Vector的相关API处理Array内的元素。
方案2:解析为业务数据类型列表(更推荐)
你可以提前定义和JSON结构匹配的数据类型,自动派生Aeson的FromJSON实例,直接解析为业务对象列表,后续处理更方便:
{-# LANGUAGE DeriveGeneric #-} import GHC.Generics (Generic) import Data.Aeson (FromJSON, parseMaybe) import Data.Text (Text) -- 对应accounts数组内每个对象的authorizations字段结构 data Authorization = Authorization { apex :: Bool , levelTwoQuotes :: Bool , stockTrading :: Bool , marginTrading :: Bool , streamingNews :: Bool , optionTradingLevel :: Text , streamerAccess :: Bool , advancedMargin :: Bool , scottradeAccount :: Bool } deriving (Show, Generic) instance FromJSON Authorization -- 对应accounts数组内的单个对象结构 data Account = Account { accountId :: Text , displayName :: Text , accountCdDomainId :: Text , company :: Text , segment :: Text , acl :: Text , authorizations :: Authorization } deriving (Show, Generic) instance FromJSON Account
解析时直接声明为[Account]类型即可:
-- 解析为Account类型的列表 fromJust (parseMaybe (\o -> o .: ("accounts" :: Text)) myobject) :: [Account]
注意事项
生产环境建议避免使用fromJust,如果解析失败(比如JSON结构变化、字段缺失)会直接导致程序崩溃,最好通过模式匹配处理Maybe的两种分支,自定义异常提示逻辑。
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

