haskellalgebraic-data-typesaesonto-json

Encoding Algebraic Data Types with Aeson in Haskell


I have the following ADT implementation:

data FeatureValue =
    FvInt Int
  | FvFloat Float
  | FvText Text
  | FvBool Bool
  deriving Show

data ApiResponse =
    Online [[Maybe FeatureValue]]
  | Offline [[[Maybe FeatureValue]]]
  deriving Show

An example value to be encoded might be:

example :: ApiResponse
example =
    Online [
        [Just (FvInt 10), Nothing, Just (FvText "foo"), Just (FvFloat 1.42)],
        [Nothing, Just (FvBool False), Just (FvText "bar"), Nothing]
    ]

which would result in the following JSON:

[
    [10, null, "foo", 1.42],
    [null, false, "bar", null]
]

I'm struggling on how to derive the ToJSON instance on FeatureValue in particular. Documentation on ADT encoding with Aeson is particularly sparse (example, the otherwise great Aelve Guide which features a glorious "Summary: TODO" for the section concerning ADT encoding/decoding).


Solution

  • From the documentation, we simply need to provide a function of type FeatureValue -> Value. The definition of Value is also documented and fully exported. So just follow your nose.

    instance ToJSON FeatureValue where
        toJSON (FvInt n) = Number (fromIntegral n)
        toJSON (FvFloat f) = Number (realToFrac f)
        toJSON (FvText t) = String t
        toJSON (FvBool b) = Bool b