anchor.diff:              else buildSimpleOptional ty s.Value
           | OptionalBoolData(v) ->
               if v then (box (Some(true))) else box None
  +        | ListData(ty, li) ->
  +            li |> buildSimpleList ty
           | RecordData(ty, data) ->
               FSharpValue.MakeRecord(ty, data |> Array.map buildType)
           | UnionData(o) ->
  
positive.code:                     if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<_ option> then
                          let genTy = ty.GetGenericArguments().[0]
                          if genTy = typeof<string> then
                              (field.Name, Optional((makeName field.Name), description, PrimitiveString))
                          else if genTy = typeof<int> then
                              (field.Name, Optional((makeName field.Name), description, PrimitiveInt))
                          else if genTy = typeof<double> then
                              (field.Name, Optional((makeName field.Name), description, PrimitiveDouble))
                          else if genTy = typeof<DateTime> then
                              (field.Name, Optional((makeName field.Name), description, PrimitiveDateTime))
                          else if genTy = typeof<bool> then
                              (field.Name, OptionalBool((makeName field.Name), description))
                          else if genTy |> FSharpType.IsUnion then
                              let cases = FSharpType.GetUnionCases genTy
                              let isSimple = cases |> Array.map (fun caseInfo -> caseInfo.GetFields() |> Array.isEmpty) |> Array.tryFind not |> Option.isNone
                              if isSimple then
                                  (field.Name, Optional((makeName field.Name), description, PrimitiveUnion(genTy)))
                              else
                                  (field.Name, Invalid)
                          else
                              (field.Name, Invalid)
                      else if ty |> FSharpType.IsRecord then
                          let a = getArgs ty
                          if a = Invalid then (field.Name, Invalid)
                          else (field.Name, a)
                      else if ty |> FSharpType.IsUnion then
                          let cases = FSharpType.GetUnionCases ty
                          let isSimple = cases |> Array.map (fun caseInfo -> caseInfo.GetFields() |> Array.isEmpty) |> Array.tryFind not |> Option.isNone
                          if isSimple then
                              (field.Name, Required((makeName field.Name), description, PrimitiveUnion(ty)))
                          else
                              (field.Name, getArgs ty)
                      else if ty = typeof<string> then
                          (field.Name, Required((makeName field.Name), description, PrimitiveString))
                      else if ty = typeof<int> then
                          (field.Name, Required((makeName field.Name), description, PrimitiveInt))
                      else if ty = typeof<double> then
                          (field.Name, Required((makeName field.Name), description, PrimitiveDouble))
                      else if ty = typeof<DateTime> then
                          (field.Name, Required((makeName field.Name), description, PrimitiveDateTime))
                      else if ty = typeof<bool> then
                          (field.Name, Required((makeName field.Name), description, PrimitiveBool))
                      else
                          (field.Name, Invalid))
              |> fun x ->
                  let isInvalid = x |> Array.map snd |> Array.tryFind (function | Invalid -> true | _ -> false) |> Option.isSome
                  if isInvalid then Invalid
                  else Record(ty, x)
          else
              Invalid
  
      let rec private doParse typeInfo (args:string[]) : (string[] * ArgParserDataInfo) =
          match typeInfo with
          | Required(matchString, _, ty) ->
              let i = args |> Array.tryFindIndex (fun x -> x = matchString)
              if i |> Option.isNone then
                  (args, RequiredData(ty, None))
  
negative.code:                         (newArgs, newOutput::output))
                      (args, [])
              (args, RecordData(ty, (data |> List.rev |> List.toArray)))
          | ArgUnion(ty, fields) ->
              let data =
                  fields
                  |> Array.zip (ty |> FSharpType.GetUnionCases)
  