title: Haskell Aeson with Sum Types
body: <p>I have a sum data type that looks like this:</p>
  
  <pre><code>data Declaration =
      IndDecl { what :: String, name :: String, argnames :: Maybe [String], constructors :: [Constructor] }
      | TypeDecl { what :: String, name :: String, argnames :: Maybe [String], value :: Maybe Arg }
      | FixDecl { what :: String, fixlist :: Maybe [Fixitem] }
      | TermDecl { what :: String, name :: String, typ :: Maybe Typ, value :: Maybe Arg }
      deriving (Show, Eq)
  </code></pre>
  
  <p>And I'm deriving the JSON serializer/deserializer using <code>Data.Aeson.TH</code> with the following options:</p>
  
  <pre><code>$(deriveJSON defaultOptions { sumEncoding = UntaggedValue } ''Declaration)
  </code></pre>
  
  <p>That removes the tag from the JSON construction. At the same time, I think my data already has a tag, which is the <code>what</code> field. It can be one of the following:</p>
  
  <pre><code>IndDecl : "decl:ind" 
  FixDecl : "decl:fix"
  </code></pre>
  
  <p>etc. So the fact that I'm using an Untagged configuration for my JSON deserialized objects is kind of worrisome. How can I make Aeson derive JSON stubs based on the tags that my data already has? </p>
  
  <p>Or maybe it's a better idea to remove the <code>what</code> field and let Aeson add a "tag" field which describes the constructor?</p>
  
  <p>EDIT: I tried the latter, by adding a tag field. Now it looks like:</p>
  
  <pre><code>-- Declarations
  data Declaration =
      IndDecl { what :: String, tag :: String, name :: String, argnames :: Maybe [String], constructors :: [Constructor] }
      | TypeDecl { what :: String, tag :: String, name :: String, argnames :: Maybe [String], value :: Maybe Arg }
      | FixDecl { what :: String, tag :: String, fixlist :: Maybe [Fixitem] }
      | TermDecl { what :: String, tag :: String, name :: String, typ :: Maybe Typ, value :: Maybe Arg }
      deriving (Show, Eq)
  </code></pre>
  
  <p>However, I get the following error:</p>
  
  <blockquote>
    <p>Error in $.declarations[0]: key "tag" not present</p>
  </blockquote>
  
  <p>Which I don't understand, since I created a "tag" field.</p>