1

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).

Jivan
  • 21,522
  • 15
  • 80
  • 131
  • 1
    have you tried the official [Hackage](https://hackage.haskell.org/package/aeson-1.5.6.0/docs/Data-Aeson.html) documentation? I find Aeson to be one of the best-documented of the commonly-used packages there - if you're struggling with implemented a particular aspect then you could edit your question to give details. – Robin Zigmond Apr 27 '21 at 15:43
  • I did find a mention of "simple sum types" using the example of `data Color = Red | Green | Blue` but I didn't find any mention of how to deal with ADTs holding values. – Jivan Apr 27 '21 at 15:50

1 Answers1

5

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
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380