Haskell - 使用 aeson 生成 JSON 会给出错误的字段顺序
Haskell - generating JSON with aeson gives incorrect order of fields
我正在尝试将数据类型编码为 JSON:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
import Data.Aeson
data Trend = Trend
{ period :: String
, africa :: String
, americas :: String
, asia :: String
} deriving Show
instance ToJSON Trend where
toJSON Trend{..} =
object [ "Period" .= period
, "Africa" .= africa
, "Americas" .= americas
, "Asia" .= asia
]
test = Trend {period = "2013", africa = "1", americas = "2", asia = "3"}
给出:
λ: encode test
λ: "{\"Asia\":\"3\",\"Period\":\"2013\",\"Africa\":\"1\",\"Americas\":\"2\"}"
我不明白为什么生成的 JSON 字段的顺序与我的数据类型不同。
我期望输出为 {period, africa, americas, asia} 而我得到的是 {asia, period, africa, americas)
我知道在传递信息时,顺序并不重要,但我很好奇为什么会这样。
它发生的原因是因为 Aeson 对象只是一个 HashMap,当 aeson 将 HashMap 转换为文本时,它只是按照 HashMap returns 它们的顺序序列化键值对 - 这可能与插入密钥的顺序无关。
您可以使用自 aeson-0.10
以来可用的 toEncoding
方法(但如果可能,请使用 aeson-0.11
)。在这种情况下,您可以更好地控制生成的结构:
instance ToJSON Trend where
toJSON Trend{..} =
object [ "Period" .= period
, "Africa" .= africa
, "Americas" .= americas
, "Asia" .= asia
]
toEncoding Trend {..} =
pairs $ "Period" .= period
<> "Africa" .= africa
<> "Americas" .= americas
<> "Asia" .= asia
或者如果这么简单,值得使用Generic
推导
instance ToJSON Trend where
toJSON = genericToJSON defaultOptions { fieldLabelModifier = capitaliseFirst }
where
capitaliseFirst (x:xs) = toUpper x : xs
capitaliseFirst [] = []
我正在尝试将数据类型编码为 JSON:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
import Data.Aeson
data Trend = Trend
{ period :: String
, africa :: String
, americas :: String
, asia :: String
} deriving Show
instance ToJSON Trend where
toJSON Trend{..} =
object [ "Period" .= period
, "Africa" .= africa
, "Americas" .= americas
, "Asia" .= asia
]
test = Trend {period = "2013", africa = "1", americas = "2", asia = "3"}
给出:
λ: encode test
λ: "{\"Asia\":\"3\",\"Period\":\"2013\",\"Africa\":\"1\",\"Americas\":\"2\"}"
我不明白为什么生成的 JSON 字段的顺序与我的数据类型不同。
我期望输出为 {period, africa, americas, asia} 而我得到的是 {asia, period, africa, americas)
我知道在传递信息时,顺序并不重要,但我很好奇为什么会这样。
它发生的原因是因为 Aeson 对象只是一个 HashMap,当 aeson 将 HashMap 转换为文本时,它只是按照 HashMap returns 它们的顺序序列化键值对 - 这可能与插入密钥的顺序无关。
您可以使用自 aeson-0.10
以来可用的 toEncoding
方法(但如果可能,请使用 aeson-0.11
)。在这种情况下,您可以更好地控制生成的结构:
instance ToJSON Trend where
toJSON Trend{..} =
object [ "Period" .= period
, "Africa" .= africa
, "Americas" .= americas
, "Asia" .= asia
]
toEncoding Trend {..} =
pairs $ "Period" .= period
<> "Africa" .= africa
<> "Americas" .= americas
<> "Asia" .= asia
或者如果这么简单,值得使用Generic
推导
instance ToJSON Trend where
toJSON = genericToJSON defaultOptions { fieldLabelModifier = capitaliseFirst }
where
capitaliseFirst (x:xs) = toUpper x : xs
capitaliseFirst [] = []