Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Aeson does not support Maybe on nested records #80

sseveran opened this Issue · 12 comments

4 participants


This may be related to some of the other issues listed. I am unable to mark fields on nested records as Maybe. It compiles fine buy requires the fields to be in the JSON at runtime.

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Aeson
import Data.Text
import qualified Data.ByteString.Lazy as BL
import Data.ByteString.Lazy.Char8 ()

import GHC.Generics
import Data.Attoparsec.ByteString.Lazy as ABl

data RootRecord = RootRecord{
  field1 :: Maybe Text,
  field2 :: SubRecord
} deriving (Generic,Show)

data SubRecord = SubRecord{
  field3 :: Maybe Text
} deriving (Generic, Show)

instance FromJSON RootRecord
instance FromJSON SubRecord

main = do
  let jsonString :: BL.ByteString = "{ \"field1\" :\"foo\", \"field2\": {}}"
  let val :: Maybe (Value) = maybeResult $ ABl.parse json' jsonString
  foo <- case val of
        Just x -> 
          case fromJSON x of
            Success y -> return y
            Error str -> fail str
        Nothing -> error "No Parse"
  print (foo :: RootRecord)

Note that this has nothing to do with nested records. If you leave out field1 of the RootRecord it also gives an error.

I would like to have this special case for Maybe fields myself. I'm planning to work on aeson next week (probably the weekend). I'll see if I can add this to both the GHC Generics and TH code (I think it's important that both have the same semantics).


I had not noticed that and you are indeed correct. @NathanHowell is also working on this issue for Generics on our side so he should hopefully send a patch over.


We have decided to wait for a fix since it needs to be done for both Generics and TH.


Any movement on this?


I have a patch ready for TH but it's not really polished and documented yet. The patch also allows you to parameterize the encoding using these options:

data Options = Options
    { fieldNameModifier :: String -> String
    , nullaryToString   :: Bool
    , sumEncoding       :: SumEncoding

data SumEncoding =
  | ObjectWithType { typeFieldName  :: String
                   , valueFieldName :: String

defaultOptions :: Options
defaultOptions = Options
                 { fieldNameModifier = id
                 , nullaryToString   = True
                 , sumEncoding       = TwoElemArray

I try to submit a pull request this week.


Was this ever resolved? I just ran into this issue myself.


I used the patch referenced above for TH and that has worked out ok for me.


Cool, I was just wondering if the patch was upstream and I didn't have to do anything except update. I'm lazy like that :-)


I've made a pull request for the TH code. See #97.


I've applied @basvandijk's patch (thanks!), still waiting on what to do for GHC Generics.


The GHC Generics and TH encoders/decoders now both accept the encoding Options. So I consider this issue fixed.

@basvandijk basvandijk closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.