Refactoring boilerplate from sum types

A simple demonstration of extracting boilerplate from Aeson code handling a Just and a Nothing case of a Maybe value.

instance ToJSON Query where    
  toJSON (TermQuery (Term termField termValue) (Just boost)) =
    object ["term" .=
            object [termField .=
                    object ["value" .= termValue
                           , "boost" .= boost]]]
  toJSON (TermQuery (Term termField termValue) Nothing) =
    object ["term" .=
            object [termField .=
                    object ["value" .= termValue]]]

This needed DRY’d up, so I decided to take advantage of the Monoid instance on lists to merge them after turning the Maybe value into a 1 or 0 kv-pair list. I could probably be more clever about this, so if anybody has suggestions I’d like to hear them.

instance ToJSON Query where    
  toJSON (TermQuery (Term termField termValue) boost) =
    object ["term" .=
            object [termField .= object merged]]
    where
      base = ["value" .= termValue]
      boosted = case boost of
        (Just boostValue) -> ["boost" .= boostValue]
        Nothing           -> []
      merged = mappend base boosted

I know this site is a bit of a disaster zone, but if you like my writing or think you could learn something useful from me, please take a look at the book I've been writing with my coauthor Julie. There's a free sample available too!