Haskell: 带aeson的动态对象字段名
Haskell: Dynamic object field name with aeson
如果我有一个数据结构从 readFile
中获取两个值;我如何使用这些值作为我的 toJSON
实例声明的字段名?
例如在下面的代码中,名称“2015”和“2016”将根据输入文件进行更改。
data MyOutput = MyOutput
{ periodOne :: YearInfo
, periodTwo :: YearInfo
, updateStamp :: String
} deriving (Show)
instance ToJSON MyOutput where
toJSON MyOutput {..} =
object [ "2015" .= periodOne
, "2016" .= periodTwo
, "Data up to" .= updateStamp
]
不幸的是 ToJSON
实例不能依赖于数据结构外部的值。
我的建议是更改数据结构以包含 periodOne
和 periodTwo
的字段名称:
data MyOutput = MyOutput {
periodOneName, periodTwoName :: String,
periodOne, periodTwo :: YearInfo
...
}
现在 toJSON
实例可以访问期间的名称。
完整示例:
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
import qualified Data.Text as T
type YearInfo = [ Int ]
data MyOutput = MyOutput
{ periodOne :: YearInfo
, periodTwo :: YearInfo
, periodOneName :: T.Text
, periodTwoName :: T.Text
, updateStamp :: String
} deriving (Show)
instance ToJSON MyOutput where
toJSON MyOutput {..} =
object [ periodOneName .= toJSON periodOne
, periodTwoName .= toJSON periodTwo
, "Data up to" .= toJSON updateStamp
]
如果我有一个数据结构从 readFile
中获取两个值;我如何使用这些值作为我的 toJSON
实例声明的字段名?
例如在下面的代码中,名称“2015”和“2016”将根据输入文件进行更改。
data MyOutput = MyOutput
{ periodOne :: YearInfo
, periodTwo :: YearInfo
, updateStamp :: String
} deriving (Show)
instance ToJSON MyOutput where
toJSON MyOutput {..} =
object [ "2015" .= periodOne
, "2016" .= periodTwo
, "Data up to" .= updateStamp
]
不幸的是 ToJSON
实例不能依赖于数据结构外部的值。
我的建议是更改数据结构以包含 periodOne
和 periodTwo
的字段名称:
data MyOutput = MyOutput {
periodOneName, periodTwoName :: String,
periodOne, periodTwo :: YearInfo
...
}
现在 toJSON
实例可以访问期间的名称。
完整示例:
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
import qualified Data.Text as T
type YearInfo = [ Int ]
data MyOutput = MyOutput
{ periodOne :: YearInfo
, periodTwo :: YearInfo
, periodOneName :: T.Text
, periodTwoName :: T.Text
, updateStamp :: String
} deriving (Show)
instance ToJSON MyOutput where
toJSON MyOutput {..} =
object [ periodOneName .= toJSON periodOne
, periodTwoName .= toJSON periodTwo
, "Data up to" .= toJSON updateStamp
]