Aeson does not support Maybe on nested records #80

sseveran opened this Issue Jun 25, 2012 · 12 comments


None yet

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.

sseveran commented Sep 2, 2012

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

sseveran commented Sep 2, 2012

Our fork has it applied.


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

bos commented Jan 15, 2013

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 Apr 21, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment