在使用 Aeson 展开 JSON 对象时,是否有一种干净的方法来保留信息?
Is there a clean way to retain information while unwrapping a JSON object with Aeson?
我正在尝试解析一个 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
值构造函数?
从 @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
我正在尝试解析一个 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
值构造函数?
从 @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