我正在尝试解析JSON对象,该对象由以下“模型架构”描述:
{
"(archived|active)_org": {
"id": "",
"description": "",
"reference": "",
"bucket_name": "",
"version": 0
}
}
(直接来自API documentation。)
我正在尝试使用Aeson将其解析为以下类型:
data Org = Org { active :: Bool
, orgId :: Text
, description :: Maybe Text
, reference :: Maybe Text
, version :: Int
} deriving (Show, Eq)
我得到了这个:
instance FromJSON Org where
parseJSON (Object v) = do
Just (Object v') <- v .: "active_org"
orgId <- v' .: "id"
description <- v' .:? "description"
reference <- v' .:? "reference"
version <- v' .: "version"
return $ Org True orgId description reference version
parseJSON _ = mzero
只要消耗的JSON被标记为“active_org”,该实现就会起作用,但如果提供“archived_org”,当然会失败。如何概括以涵盖这两种情况,并根据它是“active_org”还是“archived_org”将第一个参数更改为Org
值构造函数?
答案 0 :(得分:3)
根据@ user2407038的优秀评论,我得到了以下内容:
{-# LANGUAGE TupleSections #-}
instance FromJSON Org where
parseJSON (Object v) = ((True,) <$> (v .: "active_org"))
<|> ((False,) <$> (v .: "archived_org"))
>>= inner
where inner (b, Object v') = Org b
<$> v' .: "id"
<*> v' .:? "description"
<*> v' .:? "reference"
<*> v' .: "version"
inner (_, _) = mzero
parseJSON _ = mzero