Haskell: имя поля динамического объекта с 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
           ]

person matt    schedule 20.06.2016    source источник


Ответы (1)


К сожалению, экземпляры 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
           ]
person ErikR    schedule 20.06.2016
comment
не могли бы вы написать экземпляр ToJson. - person matt; 20.06.2016