如何在 Haskell 中解析 JSON,其中字段名称可以是多个值之一,但应转换为单个 Haskell 类型?

问题描述 投票:0回答:1

假设我有以下 JSON 值。

{
  "fieldName1": 5,
  "value1": "Hello"
}

{
  "fieldName2": 7,
  "value1": "Welcome"
}

我在 Haskell 中有以下类型。

data Greeting 
  = Greeting
      {
        count :: Int,
        name :: Text
      }
  deriving (Generic, Show, Eq)

如何将此 JSON 解析为 Haskell,其中

fieldName1
fieldName2
值应解析为
count
值?

我尝试通过执行如下所示的操作来解决此问题。

instance FromJSON Greeting where
  parseJSON = withObject "Greeting" $ \obj -> do
    count1 <- obj .:? "fieldName1"
    count2 <- obj .:? "fieldName2"
    name <- obj .: "value1"
    count <-
      case (count1, count2) of
        (Just count, Nothing) -> return count
        (Nothing, Just count) -> return count
        _ -> fail $ Text.unpack "Field missing"
    return Greeting {count = count, name = name}

它可以工作,但非常麻烦,如果有超过 2 个替代值,它就会变得更加复杂。有什么办法可以更简单的解决这个问题吗?

json parsing haskell aeson
1个回答
0
投票

稍微好一点的变体:

instance FromJSON Greeting where
  parseJSON = withObject "Greeting" $ \obj -> do
    count1 <- obj .:? "fieldName1"
    count2 <- obj .:? "fieldName2"
    name <- obj .: "value1"
    let count = maybe (fail $ Text.unpack "Field missing")
                      return
                      (count1 <|> count2)
    return Greeting {count = count, name = name}
© www.soinside.com 2019 - 2024. All rights reserved.