packages feed

hydra-kernel-0.18.0: src/main/haskell/Hydra/Core/Decoding.hs

-- Note: this is an automatically generated file. Do not edit.

-- | Functions for generating term decoders from type modules

module Hydra.Core.Decoding where

import qualified Hydra.Core.Annotations as Annotations
import qualified Hydra.Core.Ast as Ast
import qualified Hydra.Core.Coders as Coders
import qualified Hydra.Core.Constants as Constants
import qualified Hydra.Core.Decode.Model as DecodeModel
import qualified Hydra.Core.Diff as Diff
import qualified Hydra.Core.Docs as Docs
import qualified Hydra.Core.Encode.Model as EncodeModel
import qualified Hydra.Core.Error.Checking as Checking
import qualified Hydra.Core.Error.File as ErrorFile
import qualified Hydra.Core.Error.Model as ErrorModel
import qualified Hydra.Core.Error.Packaging as ErrorPackaging
import qualified Hydra.Core.Error.System as ErrorSystem
import qualified Hydra.Core.Errors as Errors
import qualified Hydra.Core.Extract.Model as ExtractModel
import qualified Hydra.Core.File as File
import qualified Hydra.Core.Formatting as Formatting
import qualified Hydra.Core.Graph as Graph
import qualified Hydra.Core.Json.Model as JsonModel
import qualified Hydra.Core.Lexical as Lexical
import qualified Hydra.Core.Overlay.Haskell.Lib.Eithers as Eithers
import qualified Hydra.Core.Overlay.Haskell.Lib.Lists as Lists
import qualified Hydra.Core.Overlay.Haskell.Lib.Logic as Logic
import qualified Hydra.Core.Overlay.Haskell.Lib.Maps as Maps
import qualified Hydra.Core.Overlay.Haskell.Lib.Optionals as Optionals
import qualified Hydra.Core.Overlay.Haskell.Lib.Sets as Sets
import qualified Hydra.Core.Overlay.Haskell.Lib.Strings as Strings
import qualified Hydra.Core.Markdown as Markdown
import qualified Hydra.Core.Model as Model
import qualified Hydra.Core.Names as Names
import qualified Hydra.Core.Packaging as Packaging
import qualified Hydra.Core.Parsing as Parsing
import qualified Hydra.Core.Paths as Paths
import qualified Hydra.Core.Predicates as Predicates
import qualified Hydra.Core.Print.Model as PrintModel
import qualified Hydra.Core.Query as Query
import qualified Hydra.Core.Regex as Regex
import qualified Hydra.Core.Relational as Relational
import qualified Hydra.Core.Rewriting as Rewriting
import qualified Hydra.Core.Scoping as Scoping
import qualified Hydra.Core.System as System
import qualified Hydra.Core.Tabular as Tabular
import qualified Hydra.Core.Testing as Testing
import qualified Hydra.Core.Time as Time
import qualified Hydra.Core.Topology as Topology
import qualified Hydra.Core.Typed as Typed
import qualified Hydra.Core.Typing as Typing
import qualified Hydra.Core.Util as Util
import qualified Hydra.Core.Validation as Validation
import qualified Hydra.Core.Variants as Variants
import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, lines, map, pure, sum, unlines)
import qualified Data.Scientific as Sci
import Data.Void

-- | Left-apply type-variable params to a base type in binder order (fixes param reversal)
applyForallParamsInOrder :: Model.Type -> [Model.Name] -> Model.Type
applyForallParamsInOrder base params =
    Lists.foldl (\acc -> \p -> Model.TypeApplication (Model.ApplicationType {
      Model.applicationTypeFunction = acc,
      Model.applicationTypeArgument = (Model.TypeVariable p)})) base params

-- | Collect forall type variable names from a type
collectForallVariables :: Model.Type -> [Model.Name]
collectForallVariables typ =
    case typ of
      Model.TypeAnnotated v0 -> collectForallVariables (Model.annotatedTypeBody v0)
      Model.TypeForall v0 -> Lists.cons (Model.forallTypeParameter v0) (collectForallVariables (Model.forallTypeBody v0))
      _ -> []

-- | Collect type variables needing Ord constraints (from Map key and Set element types)
collectOrdConstrainedVariables :: Model.Type -> [Model.Name]
collectOrdConstrainedVariables typ =
    case typ of
      Model.TypeAnnotated v0 -> collectOrdConstrainedVariables (Model.annotatedTypeBody v0)
      Model.TypeApplication v0 -> Lists.concat2 (collectOrdConstrainedVariables (Model.applicationTypeFunction v0)) (collectOrdConstrainedVariables (Model.applicationTypeArgument v0))
      Model.TypeEffect v0 -> collectOrdConstrainedVariables v0
      Model.TypeEither v0 -> Lists.concat2 (collectOrdConstrainedVariables (Model.eitherTypeLeft v0)) (collectOrdConstrainedVariables (Model.eitherTypeRight v0))
      Model.TypeForall v0 -> collectOrdConstrainedVariables (Model.forallTypeBody v0)
      Model.TypeList v0 -> collectOrdConstrainedVariables v0
      Model.TypeMap v0 -> Lists.concat [
        collectTypeVariablesFromType (Model.mapTypeKeys v0),
        (collectOrdConstrainedVariables (Model.mapTypeKeys v0)),
        (collectOrdConstrainedVariables (Model.mapTypeValues v0))]
      Model.TypeOptional v0 -> collectOrdConstrainedVariables v0
      Model.TypePair v0 -> Lists.concat2 (collectOrdConstrainedVariables (Model.pairTypeFirst v0)) (collectOrdConstrainedVariables (Model.pairTypeSecond v0))
      Model.TypeRecord v0 -> Lists.concat (Lists.map (\ft -> collectOrdConstrainedVariables (Model.fieldTypeType ft)) v0)
      Model.TypeSet v0 -> Lists.concat2 (collectTypeVariablesFromType v0) (collectOrdConstrainedVariables v0)
      Model.TypeUnion v0 -> Lists.concat (Lists.map (\ft -> collectOrdConstrainedVariables (Model.fieldTypeType ft)) v0)
      Model.TypeWrap v0 -> collectOrdConstrainedVariables v0
      _ -> []

-- | Collect type variable names from a type (forall parameters only)
collectTypeVariables :: Model.Type -> [Model.Name]
collectTypeVariables typ = collectForallVariables typ

-- | Collect all type variable names from a type expression
collectTypeVariablesFromType :: Model.Type -> [Model.Name]
collectTypeVariablesFromType typ =
    case typ of
      Model.TypeAnnotated v0 -> collectTypeVariablesFromType (Model.annotatedTypeBody v0)
      Model.TypeApplication v0 -> Lists.concat2 (collectTypeVariablesFromType (Model.applicationTypeFunction v0)) (collectTypeVariablesFromType (Model.applicationTypeArgument v0))
      Model.TypeEffect v0 -> collectTypeVariablesFromType v0
      Model.TypeEither v0 -> Lists.concat2 (collectTypeVariablesFromType (Model.eitherTypeLeft v0)) (collectTypeVariablesFromType (Model.eitherTypeRight v0))
      Model.TypeForall v0 -> collectTypeVariablesFromType (Model.forallTypeBody v0)
      Model.TypeList v0 -> collectTypeVariablesFromType v0
      Model.TypeMap v0 -> Lists.concat2 (collectTypeVariablesFromType (Model.mapTypeKeys v0)) (collectTypeVariablesFromType (Model.mapTypeValues v0))
      Model.TypeOptional v0 -> collectTypeVariablesFromType v0
      Model.TypePair v0 -> Lists.concat2 (collectTypeVariablesFromType (Model.pairTypeFirst v0)) (collectTypeVariablesFromType (Model.pairTypeSecond v0))
      Model.TypeRecord v0 -> Lists.concat (Lists.map (\ft -> collectTypeVariablesFromType (Model.fieldTypeType ft)) v0)
      Model.TypeSet v0 -> collectTypeVariablesFromType v0
      Model.TypeUnion v0 -> Lists.concat (Lists.map (\ft -> collectTypeVariablesFromType (Model.fieldTypeType ft)) v0)
      Model.TypeVariable v0 -> [
        v0]
      Model.TypeWrap v0 -> collectTypeVariablesFromType v0
      _ -> []

-- | Transform a type binding into a decoder binding
decodeBinding :: t0 -> Graph.Graph -> Model.Binding -> Either Errors.DecodingError Model.Binding
decodeBinding cx graph b =
    Eithers.bind (DecodeModel.type_ graph (Model.bindingTerm b)) (\typ ->
      let rtype = decoderFullResultTypeNamed (Model.bindingName b) typ
          rawBody = decodeTypeNamed (Model.bindingName b) typ rtype
          description =
                  Strings.concat [
                    "Decoder for ",
                    (Model.unName (Model.bindingName b))]
      in (Right (Model.Binding {
        Model.bindingName = (decodeBindingName (Model.bindingName b)),
        Model.bindingTerm = (Annotations.setTermDescription (Just description) rawBody),
        Model.bindingTypeScheme = (Just (decoderTypeSchemeNamed (Model.bindingName b) typ))})))

-- | Generate a binding name for a decoder function from a type name
decodeBindingName :: Model.Name -> Model.Name
decodeBindingName = Names.derivedBindingName [
  "decode"] True

-- | Generate a decoder for an Either type
decodeEitherType :: Model.EitherType -> Model.Term
decodeEitherType et =

      let leftDecoder = decodeType (Model.eitherTypeLeft et)
          rightDecoder = decodeType (Model.eitherTypeRight et)
      in (Model.TermApplication (Model.Application {
        Model.applicationFunction = (Model.TermApplication (Model.Application {
          Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
            Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
              Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.extract.model.decodeEither")),
              Model.typeApplicationTermType = (decoderFullResultType (Model.eitherTypeLeft et))})),
            Model.typeApplicationTermType = (decoderFullResultType (Model.eitherTypeRight et))})),
          Model.applicationArgument = leftDecoder})),
        Model.applicationArgument = rightDecoder}))

-- | Generate a decoder for a polymorphic (forall) type
decodeForallType :: Model.ForallType -> Model.Term
decodeForallType ft =
    Model.TermLambda (Model.Lambda {
      Model.lambdaParameter = (decodeBindingName (Model.forallTypeParameter ft)),
      Model.lambdaDomain = (Just (Model.TypeFunction (Model.FunctionType {
        Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.graph.Graph")),
        Model.functionTypeCodomain = (Model.TypeFunction (Model.FunctionType {
          Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.model.Term")),
          Model.functionTypeCodomain = (Model.TypeEither (Model.EitherType {
            Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
            Model.eitherTypeRight = (Model.TypeVariable (Model.forallTypeParameter ft))}))}))}))),
      Model.lambdaBody = (decodeType (Model.forallTypeBody ft))})

-- | Generate a decoder for a list type
decodeListType :: Model.Type -> Model.Term
decodeListType elemType =

      let elemDecoder = decodeType elemType
      in (Model.TermApplication (Model.Application {
        Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
          Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.extract.model.decodeList")),
          Model.typeApplicationTermType = (decoderFullResultType elemType)})),
        Model.applicationArgument = elemDecoder}))

-- | Generate a decoder for a literal type
decodeLiteralType :: Model.LiteralType -> Model.Term
decodeLiteralType lt =
    case lt of
      Model.LiteralTypeBinary -> Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "raw"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermApplication (Model.Application {
            Model.applicationFunction = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                  Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                    Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                    Model.eitherTypeRight = (Model.TypeLiteral Model.LiteralTypeBinary)}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "err"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                  Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeBinary)}))}))})),
              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                Model.lambdaParameter = (Model.Name "stripped"),
                Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                Model.lambdaBody = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                    Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                    Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                          Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                          Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeBinary)}))),
                    Model.caseStatementCases = [
                      Model.CaseAlternative {
                        Model.caseAlternativeName = (Model.Name "literal"),
                        Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                          Model.lambdaParameter = (Model.Name "v"),
                          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                          Model.lambdaBody = (Model.TermApplication (Model.Application {
                            Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                              Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                              Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                    Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                    Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected binary literal"))})))),
                                  Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeBinary)}))),
                              Model.caseStatementCases = [
                                Model.CaseAlternative {
                                  Model.caseAlternativeName = (Model.Name "binary"),
                                  Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                    Model.lambdaParameter = (Model.Name "b"),
                                    Model.lambdaDomain = (Just (Model.TypeLiteral Model.LiteralTypeBinary)),
                                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "b")))),
                                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                      Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeBinary)}))}))}]})),
                            Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
            Model.applicationArgument = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
              Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
      Model.LiteralTypeBoolean -> Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "raw"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermApplication (Model.Application {
            Model.applicationFunction = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                  Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                    Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                    Model.eitherTypeRight = (Model.TypeLiteral Model.LiteralTypeBoolean)}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "err"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                  Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeBoolean)}))}))})),
              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                Model.lambdaParameter = (Model.Name "stripped"),
                Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                Model.lambdaBody = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                    Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                    Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                          Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                          Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeBoolean)}))),
                    Model.caseStatementCases = [
                      Model.CaseAlternative {
                        Model.caseAlternativeName = (Model.Name "literal"),
                        Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                          Model.lambdaParameter = (Model.Name "v"),
                          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                          Model.lambdaBody = (Model.TermApplication (Model.Application {
                            Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                              Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                              Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                    Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                    Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected boolean literal"))})))),
                                  Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeBoolean)}))),
                              Model.caseStatementCases = [
                                Model.CaseAlternative {
                                  Model.caseAlternativeName = (Model.Name "boolean"),
                                  Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                    Model.lambdaParameter = (Model.Name "b"),
                                    Model.lambdaDomain = (Just (Model.TypeLiteral Model.LiteralTypeBoolean)),
                                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "b")))),
                                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                      Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeBoolean)}))}))}]})),
                            Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
            Model.applicationArgument = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
              Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
      Model.LiteralTypeDecimal -> Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "raw"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermApplication (Model.Application {
            Model.applicationFunction = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                  Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                    Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                    Model.eitherTypeRight = (Model.TypeLiteral Model.LiteralTypeDecimal)}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "err"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                  Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeDecimal)}))}))})),
              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                Model.lambdaParameter = (Model.Name "stripped"),
                Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                Model.lambdaBody = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                    Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                    Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                          Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                          Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeDecimal)}))),
                    Model.caseStatementCases = [
                      Model.CaseAlternative {
                        Model.caseAlternativeName = (Model.Name "literal"),
                        Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                          Model.lambdaParameter = (Model.Name "v"),
                          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                          Model.lambdaBody = (Model.TermApplication (Model.Application {
                            Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                              Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                              Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                    Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                    Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected decimal literal"))})))),
                                  Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeDecimal)}))),
                              Model.caseStatementCases = [
                                Model.CaseAlternative {
                                  Model.caseAlternativeName = (Model.Name "decimal"),
                                  Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                    Model.lambdaParameter = (Model.Name "d"),
                                    Model.lambdaDomain = (Just (Model.TypeLiteral Model.LiteralTypeDecimal)),
                                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "d")))),
                                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                      Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeDecimal)}))}))}]})),
                            Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
            Model.applicationArgument = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
              Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
      Model.LiteralTypeFloat v0 -> case v0 of
        Model.FloatTypeFloat32 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "float32",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "float"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.FloatValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "float32",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "float32"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "f"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeFloat v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "f")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.FloatTypeFloat64 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "float64",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "float"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.FloatValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "float64",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "float64"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "f"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeFloat v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "f")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeFloat v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
      Model.LiteralTypeInteger v0 -> case v0 of
        Model.IntegerTypeBigint -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "bigint",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "bigint",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "bigint"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.IntegerTypeInt8 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "int8",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "int8",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "int8"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.IntegerTypeInt16 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "int16",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "int16",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "int16"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.IntegerTypeInt32 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "int32",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "int32",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "int32"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.IntegerTypeInt64 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "int64",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "int64",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "int64"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.IntegerTypeUint8 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "uint8",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "uint8",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "uint8"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.IntegerTypeUint16 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "uint16",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "uint16",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "uint16"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.IntegerTypeUint32 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "uint32",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "uint32",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "uint32"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
        Model.IntegerTypeUint64 -> Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "cx"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
          Model.lambdaBody = (Model.TermLambda (Model.Lambda {
            Model.lambdaParameter = (Model.Name "raw"),
            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
            Model.lambdaBody = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                      Model.eitherTypeRight = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))})),
                  Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (Model.Name "err"),
                    Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "stripped"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                  Model.lambdaBody = (Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                      Model.caseStatementCases = [
                        Model.CaseAlternative {
                          Model.caseAlternativeName = (Model.Name "literal"),
                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "v"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                                Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                                Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                        "expected ",
                                        "uint64",
                                        " literal"])))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                Model.caseStatementCases = [
                                  Model.CaseAlternative {
                                    Model.caseAlternativeName = (Model.Name "integer"),
                                    Model.caseAlternativeHandler = (Model.TermCases (Model.CaseStatement {
                                      Model.caseStatementTypeName = (Model.Name "hydra.core.model.IntegerValue"),
                                      Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                            Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                                              "expected ",
                                              "uint64",
                                              " value"])))})))),
                                          Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                        Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))),
                                      Model.caseStatementCases = [
                                        Model.CaseAlternative {
                                          Model.caseAlternativeName = (Model.Name "uint64"),
                                          Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                            Model.lambdaParameter = (Model.Name "i"),
                                            Model.lambdaDomain = (Just (Model.TypeLiteral (Model.LiteralTypeInteger v0))),
                                            Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                                Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "i")))),
                                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                              Model.typeApplicationTermType = (Model.TypeLiteral (Model.LiteralTypeInteger v0))}))}))}]}))}]})),
                              Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
              Model.applicationArgument = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})
      Model.LiteralTypeString -> Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "raw"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermApplication (Model.Application {
            Model.applicationFunction = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                  Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                    Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                    Model.eitherTypeRight = (Model.TypeLiteral Model.LiteralTypeString)}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "err"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                  Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeString)}))}))})),
              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                Model.lambdaParameter = (Model.Name "stripped"),
                Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                Model.lambdaBody = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                    Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                    Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                          Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                          Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected literal"))})))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeString)}))),
                    Model.caseStatementCases = [
                      Model.CaseAlternative {
                        Model.caseAlternativeName = (Model.Name "literal"),
                        Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                          Model.lambdaParameter = (Model.Name "v"),
                          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Literal"))),
                          Model.lambdaBody = (Model.TermApplication (Model.Application {
                            Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                              Model.caseStatementTypeName = (Model.Name "hydra.core.model.Literal"),
                              Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                    Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                    Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected string literal"))})))),
                                  Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeString)}))),
                              Model.caseStatementCases = [
                                Model.CaseAlternative {
                                  Model.caseAlternativeName = (Model.Name "string"),
                                  Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                                    Model.lambdaParameter = (Model.Name "s"),
                                    Model.lambdaDomain = (Just (Model.TypeLiteral Model.LiteralTypeString)),
                                    Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermVariable (Model.Name "s")))),
                                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                      Model.typeApplicationTermType = (Model.TypeLiteral Model.LiteralTypeString)}))}))}]})),
                            Model.applicationArgument = (Model.TermVariable (Model.Name "v"))}))}))}]})),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
            Model.applicationArgument = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
              Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))})

-- | Generate a decoder for a map type
decodeMapType :: Model.MapType -> Model.Term
decodeMapType mt =

      let keyDecoder = decodeType (Model.mapTypeKeys mt)
          valDecoder = decodeType (Model.mapTypeValues mt)
      in (Model.TermApplication (Model.Application {
        Model.applicationFunction = (Model.TermApplication (Model.Application {
          Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
            Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
              Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.extract.model.decodeMap")),
              Model.typeApplicationTermType = (decoderFullResultType (Model.mapTypeKeys mt))})),
            Model.typeApplicationTermType = (decoderFullResultType (Model.mapTypeValues mt))})),
          Model.applicationArgument = keyDecoder})),
        Model.applicationArgument = valDecoder}))

-- | Generate a decoder for an optional type
decodeMaybeType :: Model.Type -> Model.Term
decodeMaybeType elemType =

      let elemDecoder = decodeType elemType
      in (Model.TermApplication (Model.Application {
        Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
          Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.extract.model.decodeMaybe")),
          Model.typeApplicationTermType = (decoderFullResultType elemType)})),
        Model.applicationArgument = elemDecoder}))

-- | Transform a type module into a decoder module
decodeModule :: t0 -> Graph.Graph -> Packaging.Module -> Either Errors.Error (Maybe Packaging.Module)
decodeModule cx graph mod =
    Eithers.bind (filterTypeBindings cx graph (Optionals.givens (Lists.map (\d -> case d of
      Packaging.DefinitionType v0 -> Just ((\name -> \typ ->
        let schemaTerm = Model.TermVariable (Model.Name "hydra.core.model.Type")
            dataTerm =
                    Annotations.normalizeTermAnnotations (Model.TermAnnotated (Model.AnnotatedTerm {
                      Model.annotatedTermBody = (EncodeModel.type_ typ),
                      Model.annotatedTermAnnotation = (Annotations.wrapAnnotationMap (Maps.fromList [
                        (Constants.keyType, schemaTerm)]))}))
        in Model.Binding {
          Model.bindingName = name,
          Model.bindingTerm = dataTerm,
          Model.bindingTypeScheme = (Just (Model.TypeScheme {
            Model.typeSchemeVariables = [],
            Model.typeSchemeBody = (Model.TypeVariable (Model.Name "hydra.core.model.Type")),
            Model.typeSchemeConstraints = Maps.empty}))}) (Packaging.typeDefinitionName v0) (Model.typeSchemeBody (Packaging.typeDefinitionBody v0)))
      _ -> Nothing) (Packaging.moduleDefinitions mod)))) (\typeBindings -> Logic.ifElse (Lists.isEmpty typeBindings) (Right Nothing) (Eithers.bind (Eithers.mapList (\b -> Eithers.bimap (\_e -> Errors.ErrorDecoding _e) (\x -> x) (decodeBinding cx graph b)) typeBindings) (\decodedBindings ->
      let allDecodedDeps =
              Lists.distinct (Lists.map decodeModuleName (Lists.map (\dep -> Packaging.moduleDependencyModule dep) (Packaging.moduleDependencies mod)))
      in (Right (Just (Packaging.Module {
        Packaging.moduleName = (decodeModuleName (Packaging.moduleName mod)),
        Packaging.moduleMetadata = (Just (Packaging.EntityMetadata {
          Packaging.entityMetadataDescription = (Just (Strings.concat [
            "Term decoders for ",
            (Packaging.unModuleName (Packaging.moduleName mod))])),
          Packaging.entityMetadataComments = [],
          Packaging.entityMetadataSeeAlso = [],
          Packaging.entityMetadataLifecycle = Nothing,
          Packaging.entityMetadataProvisions = []})),
        Packaging.moduleDependencies = (Lists.map (\ns -> Packaging.ModuleDependency {
          Packaging.moduleDependencyModule = ns,
          Packaging.moduleDependencyPackage = Nothing}) (Lists.concat2 [
          Packaging.ModuleName "hydra.core.extract.model",
          (Packaging.ModuleName "hydra.core.lexical"),
          (Packaging.ModuleName "hydra.core.rewriting"),
          (Packaging.moduleName mod),
          (Packaging.ModuleName "hydra.core.util")] allDecodedDeps)),
        Packaging.moduleDefinitions = (Lists.map (\b -> Packaging.DefinitionTerm (Packaging.TermDefinition {
          Packaging.termDefinitionName = (Model.bindingName b),
          Packaging.termDefinitionMetadata = Nothing,
          Packaging.termDefinitionSignature = (Optionals.map Scoping.typeSchemeToTermSignature (Model.bindingTypeScheme b)),
          Packaging.termDefinitionBody = (Model.bindingTerm b)})) decodedBindings)}))))))

-- | Generate a decoder module name from a source module name
decodeModuleName :: Packaging.ModuleName -> Packaging.ModuleName
decodeModuleName = Names.derivedModuleName [
  "decode"] True

-- | Generate a decoder for a pair type
decodePairType :: Model.PairType -> Model.Term
decodePairType pt =

      let firstDecoder = decodeType (Model.pairTypeFirst pt)
          secondDecoder = decodeType (Model.pairTypeSecond pt)
      in (Model.TermApplication (Model.Application {
        Model.applicationFunction = (Model.TermApplication (Model.Application {
          Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
            Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
              Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.extract.model.decodePair")),
              Model.typeApplicationTermType = (decoderFullResultType (Model.pairTypeFirst pt))})),
            Model.typeApplicationTermType = (decoderFullResultType (Model.pairTypeSecond pt))})),
          Model.applicationArgument = firstDecoder})),
        Model.applicationArgument = secondDecoder}))

-- | Generate a decoder for a record type
decodeRecordType :: [Model.FieldType] -> Model.Term
decodeRecordType rt = decodeRecordTypeImpl (Model.Name "unknown") rt (Model.TypeVariable (Model.Name "unknown"))

-- | Generate a decoder for a record type with a type name. rtype is the fully-applied result type (e.g. Table<v>) used for the record's body annotations. (#476)
decodeRecordTypeImpl :: Model.Name -> [Model.FieldType] -> Model.Type -> Model.Term
decodeRecordTypeImpl tname rt rtype =

      let recType = rtype
          graphType = Model.TypeVariable (Model.Name "hydra.core.graph.Graph")
          termType = Model.TypeVariable (Model.Name "hydra.core.model.Term")
          decodeFieldTerm =
                  \ft -> Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermApplication (Model.Application {
                      Model.applicationFunction = (Model.TermApplication (Model.Application {
                        Model.applicationFunction = (Model.TermApplication (Model.Application {
                          Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                            Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                              Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.extract.model.requireField")),
                                Model.typeApplicationTermType = graphType})),
                              Model.typeApplicationTermType = termType})),
                            Model.typeApplicationTermType = (decoderFullResultType (Model.fieldTypeType ft))})),
                          Model.applicationArgument = (Model.TermLiteral (Model.LiteralString (Model.unName (Model.fieldTypeName ft))))})),
                        Model.applicationArgument = (decodeType (Model.fieldTypeType ft))})),
                      Model.applicationArgument = (Model.TermVariable (Model.Name "fieldMap"))})),
                    Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})
          localVarName =
                  \ft -> Model.Name (Strings.concat [
                    "field_",
                    (Model.unName (Model.fieldTypeName ft))])
          toFieldLambda =
                  \ft -> \body -> Model.TermLambda (Model.Lambda {
                    Model.lambdaParameter = (localVarName ft),
                    Model.lambdaDomain = (Just (decoderFullResultType (Model.fieldTypeType ft))),
                    Model.lambdaBody = body})
          decodeBody =
                  Lists.foldl (\acc -> \ft -> Model.TermApplication (Model.Application {
                    Model.applicationFunction = (Model.TermApplication (Model.Application {
                      Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                          Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                            Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.bind")),
                            Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                          Model.typeApplicationTermType = (decoderFullResultType (Model.fieldTypeType ft))})),
                        Model.typeApplicationTermType = recType})),
                      Model.applicationArgument = (decodeFieldTerm ft)})),
                    Model.applicationArgument = (toFieldLambda ft acc)})) (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermEither (Right (Model.TermRecord (Model.Record {
                        Model.recordTypeName = tname,
                        Model.recordFields = (Lists.map (\ft -> Model.Field {
                          Model.fieldName = (Model.fieldTypeName ft),
                          Model.fieldTerm = (Model.TermVariable (localVarName ft))}) rt)})))),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = recType})) (Lists.reverse rt)
      in (Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "raw"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermApplication (Model.Application {
            Model.applicationFunction = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                  Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                    Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                    Model.eitherTypeRight = recType}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "err"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                  Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = recType}))}))})),
              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                Model.lambdaParameter = (Model.Name "stripped"),
                Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                Model.lambdaBody = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                    Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                    Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                          Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                          Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Strings.concat [
                            "expected a record of type ",
                            (Model.unName tname)])))})))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = recType}))),
                    Model.caseStatementCases = [
                      Model.CaseAlternative {
                        Model.caseAlternativeName = (Model.Name "record"),
                        Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                          Model.lambdaParameter = (Model.Name "record"),
                          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Record"))),
                          Model.lambdaBody = (Model.TermLet (Model.Let {
                            Model.letBindings = [
                              Model.Binding {
                                Model.bindingName = (Model.Name "fieldMap"),
                                Model.bindingTerm = (Model.TermApplication (Model.Application {
                                  Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.toFieldMap")),
                                  Model.applicationArgument = (Model.TermVariable (Model.Name "record"))})),
                                Model.bindingTypeScheme = (Just (Model.TypeScheme {
                                  Model.typeSchemeVariables = [],
                                  Model.typeSchemeBody = (Model.TypeMap (Model.MapType {
                                    Model.mapTypeKeys = (Model.TypeVariable (Model.Name "hydra.core.model.Name")),
                                    Model.mapTypeValues = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                                  Model.typeSchemeConstraints = Maps.empty}))}],
                            Model.letBody = decodeBody}))}))}]})),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
            Model.applicationArgument = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
              Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))}))

-- | Generate a decoder for a record type with element name
decodeRecordTypeNamed :: Model.Name -> [Model.FieldType] -> Model.Type -> Model.Term
decodeRecordTypeNamed ename rt rtype = decodeRecordTypeImpl ename rt rtype

-- | Generate a decoder for a set type
decodeSetType :: Model.Type -> Model.Term
decodeSetType elemType =

      let elemDecoder = decodeType elemType
      in (Model.TermApplication (Model.Application {
        Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
          Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.extract.model.decodeSet")),
          Model.typeApplicationTermType = (decoderFullResultType elemType)})),
        Model.applicationArgument = elemDecoder}))

-- | Generate a decoder term for a Type
decodeType :: Model.Type -> Model.Term
decodeType typ =
    case typ of
      Model.TypeAnnotated v0 -> decodeType (Model.annotatedTypeBody v0)
      Model.TypeApplication v0 -> Model.TermApplication (Model.Application {
        Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
          Model.typeApplicationTermBody = (decodeType (Model.applicationTypeFunction v0)),
          Model.typeApplicationTermType = (decoderFullResultType (Model.applicationTypeArgument v0))})),
        Model.applicationArgument = (decodeType (Model.applicationTypeArgument v0))})
      Model.TypeEither v0 -> decodeEitherType v0
      Model.TypeForall v0 -> decodeForallType v0
      Model.TypeList v0 -> decodeListType v0
      Model.TypeLiteral v0 -> decodeLiteralType v0
      Model.TypeMap v0 -> decodeMapType v0
      Model.TypeOptional v0 -> decodeMaybeType v0
      Model.TypePair v0 -> decodePairType v0
      Model.TypeRecord v0 -> decodeRecordType v0
      Model.TypeSet v0 -> decodeSetType v0
      Model.TypeUnion v0 -> decodeUnionType v0
      Model.TypeUnit -> decodeUnitType
      Model.TypeVoid -> decodeUnitType
      Model.TypeWrap v0 -> decodeWrappedType v0
      Model.TypeVariable v0 -> Model.TermVariable (decodeBindingName v0)
      _ -> Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "t"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
            Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
              Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "unsupported type variant"))})))),
              Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
            Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))}))}))})

-- | Generate a decoder term for a Type, with element name for nominal types. rtype is the FULLY-APPLIED result type for nominal bodies (e.g. DataRow<v> for forall v. wrap...), so the body's intermediate type annotations carry the type parameters rather than a bare nominal name — otherwise Java/Scala coders emit raw types that fail to compile against the parameterized signature. (#476)
decodeTypeNamed :: Model.Name -> Model.Type -> Model.Type -> Model.Term
decodeTypeNamed ename typ rtype =
    case typ of
      Model.TypeAnnotated v0 -> decodeTypeNamed ename (Model.annotatedTypeBody v0) rtype
      Model.TypeApplication v0 -> Model.TermApplication (Model.Application {
        Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
          Model.typeApplicationTermBody = (decodeType (Model.applicationTypeFunction v0)),
          Model.typeApplicationTermType = (decoderFullResultType (Model.applicationTypeArgument v0))})),
        Model.applicationArgument = (decodeType (Model.applicationTypeArgument v0))})
      Model.TypeEither v0 -> decodeEitherType v0
      Model.TypeForall v0 -> Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (decodeBindingName (Model.forallTypeParameter v0)),
        Model.lambdaDomain = (Just (Model.TypeFunction (Model.FunctionType {
          Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.graph.Graph")),
          Model.functionTypeCodomain = (Model.TypeFunction (Model.FunctionType {
            Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.model.Term")),
            Model.functionTypeCodomain = (Model.TypeEither (Model.EitherType {
              Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
              Model.eitherTypeRight = (Model.TypeVariable (Model.forallTypeParameter v0))}))}))}))),
        Model.lambdaBody = (decodeTypeNamed ename (Model.forallTypeBody v0) rtype)})
      Model.TypeList v0 -> decodeListType v0
      Model.TypeLiteral v0 -> decodeLiteralType v0
      Model.TypeMap v0 -> decodeMapType v0
      Model.TypeOptional v0 -> decodeMaybeType v0
      Model.TypePair v0 -> decodePairType v0
      Model.TypeRecord v0 -> decodeRecordTypeNamed ename v0 rtype
      Model.TypeSet v0 -> decodeSetType v0
      Model.TypeUnion v0 -> decodeUnionTypeNamed ename v0 rtype
      Model.TypeUnit -> decodeUnitType
      Model.TypeVoid -> decodeUnitType
      Model.TypeWrap v0 -> decodeWrappedTypeNamed ename v0 rtype
      Model.TypeVariable v0 -> Model.TermVariable (decodeBindingName v0)
      _ -> Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "t"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
            Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
              Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "unsupported type variant"))})))),
              Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
            Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))}))}))})

-- | Generate a decoder for a union type
decodeUnionType :: [Model.FieldType] -> Model.Term
decodeUnionType rt = decodeUnionTypeNamed (Model.Name "unknown") rt (Model.TypeVariable (Model.Name "unknown"))

-- | Generate a decoder for a union type with the given element name. rtype is the fully-applied result type (e.g. Foo<v>) used for body annotations. (#476)
decodeUnionTypeNamed :: Model.Name -> [Model.FieldType] -> Model.Type -> Model.Term
decodeUnionTypeNamed ename rt rtype =

      let unionType = rtype
          decErrType = Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")
          nameType = Model.TypeVariable (Model.Name "hydra.core.model.Name")
          variantFnType =
                  Model.TypeFunction (Model.FunctionType {
                    Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.model.Term")),
                    Model.functionTypeCodomain = (Model.TypeEither (Model.EitherType {
                      Model.eitherTypeLeft = decErrType,
                      Model.eitherTypeRight = unionType}))})
          toVariantPair =
                  \ft ->
                    let fldType = decoderFullResultType (Model.fieldTypeType ft)
                    in (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermPair (
                          Model.TermWrap (Model.WrappedTerm {
                            Model.wrappedTermTypeName = (Model.Name "hydra.core.model.Name"),
                            Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString (Model.unName (Model.fieldTypeName ft))))}),
                          (Model.TermLambda (Model.Lambda {
                            Model.lambdaParameter = (Model.Name "input"),
                            Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                            Model.lambdaBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermApplication (Model.Application {
                                Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.map")),
                                      Model.typeApplicationTermType = fldType})),
                                    Model.typeApplicationTermType = unionType})),
                                  Model.typeApplicationTermType = decErrType})),
                                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                                  Model.lambdaParameter = (Model.Name "t"),
                                  Model.lambdaDomain = (Just fldType),
                                  Model.lambdaBody = (Model.TermInject (Model.Injection {
                                    Model.injectionTypeName = ename,
                                    Model.injectionField = Model.Field {
                                      Model.fieldName = (Model.fieldTypeName ft),
                                      Model.fieldTerm = (Model.TermVariable (Model.Name "t"))}}))}))})),
                              Model.applicationArgument = (Model.TermApplication (Model.Application {
                                Model.applicationFunction = (Model.TermApplication (Model.Application {
                                  Model.applicationFunction = (decodeType (Model.fieldTypeType ft)),
                                  Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                                Model.applicationArgument = (Model.TermVariable (Model.Name "input"))}))}))})))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Name"))})),
                      Model.typeApplicationTermType = variantFnType}))
      in (Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "raw"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermApplication (Model.Application {
            Model.applicationFunction = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                  Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                    Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                    Model.eitherTypeRight = unionType}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "err"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                  Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = unionType}))}))})),
              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                Model.lambdaParameter = (Model.Name "stripped"),
                Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                Model.lambdaBody = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                    Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                    Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                          Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                          Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected union"))})))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = unionType}))),
                    Model.caseStatementCases = [
                      Model.CaseAlternative {
                        Model.caseAlternativeName = (Model.Name "inject"),
                        Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                          Model.lambdaParameter = (Model.Name "inj"),
                          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Injection"))),
                          Model.lambdaBody = (Model.TermLet (Model.Let {
                            Model.letBindings = [
                              Model.Binding {
                                Model.bindingName = (Model.Name "field"),
                                Model.bindingTerm = (Model.TermApplication (Model.Application {
                                  Model.applicationFunction = (Model.TermProject (Model.Projection {
                                    Model.projectionTypeName = (Model.Name "hydra.core.model.Injection"),
                                    Model.projectionFieldName = (Model.Name "field")})),
                                  Model.applicationArgument = (Model.TermVariable (Model.Name "inj"))})),
                                Model.bindingTypeScheme = (Just (Model.TypeScheme {
                                  Model.typeSchemeVariables = [],
                                  Model.typeSchemeBody = (Model.TypeVariable (Model.Name "hydra.core.model.Field")),
                                  Model.typeSchemeConstraints = Maps.empty}))},
                              Model.Binding {
                                Model.bindingName = (Model.Name "fname"),
                                Model.bindingTerm = (Model.TermApplication (Model.Application {
                                  Model.applicationFunction = (Model.TermProject (Model.Projection {
                                    Model.projectionTypeName = (Model.Name "hydra.core.model.Field"),
                                    Model.projectionFieldName = (Model.Name "name")})),
                                  Model.applicationArgument = (Model.TermVariable (Model.Name "field"))})),
                                Model.bindingTypeScheme = (Just (Model.TypeScheme {
                                  Model.typeSchemeVariables = [],
                                  Model.typeSchemeBody = (Model.TypeVariable (Model.Name "hydra.core.model.Name")),
                                  Model.typeSchemeConstraints = Maps.empty}))},
                              Model.Binding {
                                Model.bindingName = (Model.Name "fterm"),
                                Model.bindingTerm = (Model.TermApplication (Model.Application {
                                  Model.applicationFunction = (Model.TermProject (Model.Projection {
                                    Model.projectionTypeName = (Model.Name "hydra.core.model.Field"),
                                    Model.projectionFieldName = (Model.Name "term")})),
                                  Model.applicationArgument = (Model.TermVariable (Model.Name "field"))})),
                                Model.bindingTypeScheme = (Just (Model.TypeScheme {
                                  Model.typeSchemeVariables = [],
                                  Model.typeSchemeBody = (Model.TypeVariable (Model.Name "hydra.core.model.Term")),
                                  Model.typeSchemeConstraints = Maps.empty}))},
                              Model.Binding {
                                Model.bindingName = (Model.Name "variantMap"),
                                Model.bindingTerm = (Model.TermApplication (Model.Application {
                                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.maps.fromList")),
                                      Model.typeApplicationTermType = nameType})),
                                    Model.typeApplicationTermType = variantFnType})),
                                  Model.applicationArgument = (Model.TermList (Lists.map toVariantPair rt))})),
                                Model.bindingTypeScheme = (Just (Model.TypeScheme {
                                  Model.typeSchemeVariables = [],
                                  Model.typeSchemeBody = (Model.TypeMap (Model.MapType {
                                    Model.mapTypeKeys = nameType,
                                    Model.mapTypeValues = variantFnType})),
                                  Model.typeSchemeConstraints = Maps.empty}))}],
                            Model.letBody = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermApplication (Model.Application {
                                Model.applicationFunction = (Model.TermApplication (Model.Application {
                                  Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.optionals.match")),
                                      Model.typeApplicationTermType = variantFnType})),
                                    Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                                      Model.eitherTypeLeft = decErrType,
                                      Model.eitherTypeRight = unionType}))})),
                                  Model.applicationArgument = (Model.TermApplication (Model.Application {
                                    Model.applicationFunction = (Model.TermApplication (Model.Application {
                                      Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                        Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                          Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.maps.lookup")),
                                          Model.typeApplicationTermType = nameType})),
                                        Model.typeApplicationTermType = variantFnType})),
                                      Model.applicationArgument = (Model.TermVariable (Model.Name "fname"))})),
                                    Model.applicationArgument = (Model.TermVariable (Model.Name "variantMap"))}))})),
                                Model.applicationArgument = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                                      Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                                      Model.wrappedTermBody = (Model.TermApplication (Model.Application {
                                        Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.lib.strings.concat")),
                                        Model.applicationArgument = (Model.TermList [
                                          Model.TermLiteral (Model.LiteralString "no such field "),
                                          (Model.TermApplication (Model.Application {
                                            Model.applicationFunction = (Model.TermUnwrap (Model.Name "hydra.core.model.Name")),
                                            Model.applicationArgument = (Model.TermVariable (Model.Name "fname"))})),
                                          (Model.TermLiteral (Model.LiteralString " in union"))])}))})))),
                                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                                  Model.typeApplicationTermType = unionType}))})),
                              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                                Model.lambdaParameter = (Model.Name "f"),
                                Model.lambdaDomain = (Just variantFnType),
                                Model.lambdaBody = (Model.TermApplication (Model.Application {
                                  Model.applicationFunction = (Model.TermVariable (Model.Name "f")),
                                  Model.applicationArgument = (Model.TermVariable (Model.Name "fterm"))}))}))}))}))}))}]})),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
            Model.applicationArgument = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
              Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))}))

-- | Generate a decoder for the unit type
decodeUnitType :: Model.Term
decodeUnitType =
    Model.TermLambda (Model.Lambda {
      Model.lambdaParameter = (Model.Name "cx"),
      Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
      Model.lambdaBody = (Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "t"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
        Model.lambdaBody = (Model.TermApplication (Model.Application {
          Model.applicationFunction = (Model.TermApplication (Model.Application {
            Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.decodeUnit")),
            Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
          Model.applicationArgument = (Model.TermVariable (Model.Name "t"))}))}))})

-- | Generate a decoder for a wrapped type
decodeWrappedType :: Model.Type -> Model.Term
decodeWrappedType wt = decodeWrappedTypeNamed (Model.Name "unknown") wt (Model.TypeVariable (Model.Name "unknown"))

-- | Generate a decoder for a wrapped type with the given element name. rtype is the fully-applied result type (e.g. DataRow<v>) used for body annotations. (#476)
decodeWrappedTypeNamed :: Model.Name -> Model.Type -> Model.Type -> Model.Term
decodeWrappedTypeNamed ename wt rtype =

      let bodyDecoder = decodeType wt
          bodyType = decoderFullResultType wt
      in (Model.TermLambda (Model.Lambda {
        Model.lambdaParameter = (Model.Name "cx"),
        Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.graph.Graph"))),
        Model.lambdaBody = (Model.TermLambda (Model.Lambda {
          Model.lambdaParameter = (Model.Name "raw"),
          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
          Model.lambdaBody = (Model.TermApplication (Model.Application {
            Model.applicationFunction = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.either")),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.model.Term"))})),
                  Model.typeApplicationTermType = (Model.TypeEither (Model.EitherType {
                    Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                    Model.eitherTypeRight = rtype}))})),
                Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                  Model.lambdaParameter = (Model.Name "err"),
                  Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))),
                  Model.lambdaBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                    Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermVariable (Model.Name "err")))),
                      Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                    Model.typeApplicationTermType = rtype}))}))})),
              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                Model.lambdaParameter = (Model.Name "stripped"),
                Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.Term"))),
                Model.lambdaBody = (Model.TermApplication (Model.Application {
                  Model.applicationFunction = (Model.TermCases (Model.CaseStatement {
                    Model.caseStatementTypeName = (Model.Name "hydra.core.model.Term"),
                    Model.caseStatementDefault = (Just (Model.TermTypeApplication (Model.TypeApplicationTerm {
                      Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                        Model.typeApplicationTermBody = (Model.TermEither (Left (Model.TermWrap (Model.WrappedTerm {
                          Model.wrappedTermTypeName = (Model.Name "hydra.core.errors.DecodingError"),
                          Model.wrappedTermBody = (Model.TermLiteral (Model.LiteralString "expected wrapped type"))})))),
                        Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                      Model.typeApplicationTermType = rtype}))),
                    Model.caseStatementCases = [
                      Model.CaseAlternative {
                        Model.caseAlternativeName = (Model.Name "wrap"),
                        Model.caseAlternativeHandler = (Model.TermLambda (Model.Lambda {
                          Model.lambdaParameter = (Model.Name "wrappedTerm"),
                          Model.lambdaDomain = (Just (Model.TypeVariable (Model.Name "hydra.core.model.WrappedTerm"))),
                          Model.lambdaBody = (Model.TermApplication (Model.Application {
                            Model.applicationFunction = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                  Model.typeApplicationTermBody = (Model.TermTypeApplication (Model.TypeApplicationTerm {
                                    Model.typeApplicationTermBody = (Model.TermVariable (Model.Name "hydra.core.lib.eithers.map")),
                                    Model.typeApplicationTermType = bodyType})),
                                  Model.typeApplicationTermType = rtype})),
                                Model.typeApplicationTermType = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError"))})),
                              Model.applicationArgument = (Model.TermLambda (Model.Lambda {
                                Model.lambdaParameter = (Model.Name "b"),
                                Model.lambdaDomain = (Just bodyType),
                                Model.lambdaBody = (Model.TermWrap (Model.WrappedTerm {
                                  Model.wrappedTermTypeName = ename,
                                  Model.wrappedTermBody = (Model.TermVariable (Model.Name "b"))}))}))})),
                            Model.applicationArgument = (Model.TermApplication (Model.Application {
                              Model.applicationFunction = (Model.TermApplication (Model.Application {
                                Model.applicationFunction = bodyDecoder,
                                Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
                              Model.applicationArgument = (Model.TermApplication (Model.Application {
                                Model.applicationFunction = (Model.TermProject (Model.Projection {
                                  Model.projectionTypeName = (Model.Name "hydra.core.model.WrappedTerm"),
                                  Model.projectionFieldName = (Model.Name "body")})),
                                Model.applicationArgument = (Model.TermVariable (Model.Name "wrappedTerm"))}))}))}))}))}]})),
                  Model.applicationArgument = (Model.TermVariable (Model.Name "stripped"))}))}))})),
            Model.applicationArgument = (Model.TermApplication (Model.Application {
              Model.applicationFunction = (Model.TermApplication (Model.Application {
                Model.applicationFunction = (Model.TermVariable (Model.Name "hydra.core.extract.model.stripWithDecodingError")),
                Model.applicationArgument = (Model.TermVariable (Model.Name "cx"))})),
              Model.applicationArgument = (Model.TermVariable (Model.Name "raw"))}))}))}))}))

-- | Get full result type for decoder
decoderFullResultType :: Model.Type -> Model.Type
decoderFullResultType typ =
    case typ of
      Model.TypeAnnotated v0 -> decoderFullResultType (Model.annotatedTypeBody v0)
      Model.TypeApplication v0 -> Model.TypeApplication (Model.ApplicationType {
        Model.applicationTypeFunction = (decoderFullResultType (Model.applicationTypeFunction v0)),
        Model.applicationTypeArgument = (Model.applicationTypeArgument v0)})
      Model.TypeEffect v0 -> Model.TypeEffect (decoderFullResultType v0)
      Model.TypeEither v0 -> Model.TypeEither (Model.EitherType {
        Model.eitherTypeLeft = (decoderFullResultType (Model.eitherTypeLeft v0)),
        Model.eitherTypeRight = (decoderFullResultType (Model.eitherTypeRight v0))})
      Model.TypeForall v0 -> applyForallParamsInOrder (decoderFullResultType (stripForalls (Model.forallTypeBody v0))) (collectForallVariables typ)
      Model.TypeList v0 -> Model.TypeList (decoderFullResultType v0)
      Model.TypeLiteral v0 -> Model.TypeLiteral v0
      Model.TypeMap v0 -> Model.TypeMap (Model.MapType {
        Model.mapTypeKeys = (decoderFullResultType (Model.mapTypeKeys v0)),
        Model.mapTypeValues = (decoderFullResultType (Model.mapTypeValues v0))})
      Model.TypeOptional v0 -> Model.TypeOptional (decoderFullResultType v0)
      Model.TypePair v0 -> Model.TypePair (Model.PairType {
        Model.pairTypeFirst = (decoderFullResultType (Model.pairTypeFirst v0)),
        Model.pairTypeSecond = (decoderFullResultType (Model.pairTypeSecond v0))})
      Model.TypeRecord _ -> Model.TypeVariable (Model.Name "hydra.core.model.Term")
      Model.TypeSet v0 -> Model.TypeSet (decoderFullResultType v0)
      Model.TypeUnion _ -> Model.TypeVariable (Model.Name "hydra.core.model.Term")
      Model.TypeUnit -> Model.TypeUnit
      Model.TypeVariable v0 -> Model.TypeVariable v0
      Model.TypeVoid -> Model.TypeVoid
      Model.TypeWrap v0 -> decoderFullResultType v0
      _ -> Model.TypeVariable (Model.Name "hydra.core.model.Term")

-- | Get full result type for decoder with element name
decoderFullResultTypeNamed :: Model.Name -> Model.Type -> Model.Type
decoderFullResultTypeNamed ename typ =
    case typ of
      Model.TypeAnnotated v0 -> decoderFullResultTypeNamed ename (Model.annotatedTypeBody v0)
      Model.TypeForall v0 -> applyForallParamsInOrder (decoderFullResultTypeNamed ename (stripForalls (Model.forallTypeBody v0))) (collectForallVariables typ)
      Model.TypeRecord _ -> Model.TypeVariable ename
      Model.TypeUnion _ -> Model.TypeVariable ename
      Model.TypeWrap _ -> Model.TypeVariable ename
      Model.TypeApplication v0 -> Model.TypeApplication (Model.ApplicationType {
        Model.applicationTypeFunction = (decoderFullResultType (Model.applicationTypeFunction v0)),
        Model.applicationTypeArgument = (Model.applicationTypeArgument v0)})
      Model.TypeEffect v0 -> Model.TypeEffect (decoderFullResultType v0)
      Model.TypeEither v0 -> Model.TypeEither (Model.EitherType {
        Model.eitherTypeLeft = (decoderFullResultType (Model.eitherTypeLeft v0)),
        Model.eitherTypeRight = (decoderFullResultType (Model.eitherTypeRight v0))})
      Model.TypeList v0 -> Model.TypeList (decoderFullResultType v0)
      Model.TypeLiteral v0 -> Model.TypeLiteral v0
      Model.TypeMap v0 -> Model.TypeMap (Model.MapType {
        Model.mapTypeKeys = (decoderFullResultType (Model.mapTypeKeys v0)),
        Model.mapTypeValues = (decoderFullResultType (Model.mapTypeValues v0))})
      Model.TypeOptional v0 -> Model.TypeOptional (decoderFullResultType v0)
      Model.TypePair v0 -> Model.TypePair (Model.PairType {
        Model.pairTypeFirst = (decoderFullResultType (Model.pairTypeFirst v0)),
        Model.pairTypeSecond = (decoderFullResultType (Model.pairTypeSecond v0))})
      Model.TypeSet v0 -> Model.TypeSet (decoderFullResultType v0)
      Model.TypeUnit -> Model.TypeUnit
      Model.TypeVariable v0 -> Model.TypeVariable v0
      Model.TypeVoid -> Model.TypeVoid
      _ -> Model.TypeVariable (Model.Name "hydra.core.model.Term")

-- | Compute the result type name for a decoder
decoderResultType :: Model.Type -> Model.Name
decoderResultType typ =
    case typ of
      Model.TypeAnnotated v0 -> decoderResultType (Model.annotatedTypeBody v0)
      Model.TypeApplication v0 -> decoderResultType (Model.applicationTypeFunction v0)
      Model.TypeForall v0 -> decoderResultType (Model.forallTypeBody v0)
      Model.TypeLiteral _ -> Model.Name "hydra.core.model.Literal"
      Model.TypeRecord _ -> Model.Name "hydra.core.model.Term"
      Model.TypeUnion _ -> Model.Name "hydra.core.model.Term"
      Model.TypeWrap _ -> Model.Name "hydra.core.model.Term"
      _ -> Model.Name "hydra.core.model.Term"

-- | Build decoder function type
decoderType :: Model.Type -> Model.Type
decoderType typ =

      let resultType = decoderFullResultType typ
          baseType =
                  Model.TypeFunction (Model.FunctionType {
                    Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.graph.Graph")),
                    Model.functionTypeCodomain = (Model.TypeFunction (Model.FunctionType {
                      Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.model.Term")),
                      Model.functionTypeCodomain = (Model.TypeEither (Model.EitherType {
                        Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                        Model.eitherTypeRight = resultType}))}))})
      in (prependForallDecoders baseType typ)

-- | Build decoder function type with element name
decoderTypeNamed :: Model.Name -> Model.Type -> Model.Type
decoderTypeNamed ename typ =

      let resultType = decoderFullResultTypeNamed ename typ
          baseType =
                  Model.TypeFunction (Model.FunctionType {
                    Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.graph.Graph")),
                    Model.functionTypeCodomain = (Model.TypeFunction (Model.FunctionType {
                      Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.model.Term")),
                      Model.functionTypeCodomain = (Model.TypeEither (Model.EitherType {
                        Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
                        Model.eitherTypeRight = resultType}))}))})
      in (prependForallDecoders baseType typ)

-- | Build type scheme for a decoder function
decoderTypeScheme :: Model.Type -> Model.TypeScheme
decoderTypeScheme typ =

      let typeVars = collectTypeVariables typ
          allOrdVars = collectOrdConstrainedVariables typ
          ordVars = Lists.filter (\v -> Lists.member v typeVars) allOrdVars
          constraints =
                  Maps.fromList (Lists.map (\v -> (
                    v,
                    Model.TypeVariableConstraints {
                      Model.typeVariableConstraintsClasses = (Sets.singleton (Model.TypeClassConstraintSimple (Model.Name "ordering")))})) ordVars)
      in Model.TypeScheme {
        Model.typeSchemeVariables = typeVars,
        Model.typeSchemeBody = (decoderType typ),
        Model.typeSchemeConstraints = constraints}

-- | Build type scheme for a decoder function with element name
decoderTypeSchemeNamed :: Model.Name -> Model.Type -> Model.TypeScheme
decoderTypeSchemeNamed ename typ =

      let typeVars = collectTypeVariables typ
          allOrdVars = collectOrdConstrainedVariables typ
          ordVars = Lists.filter (\v -> Lists.member v typeVars) allOrdVars
          constraints =
                  Maps.fromList (Lists.map (\v -> (
                    v,
                    Model.TypeVariableConstraints {
                      Model.typeVariableConstraintsClasses = (Sets.singleton (Model.TypeClassConstraintSimple (Model.Name "ordering")))})) ordVars)
      in Model.TypeScheme {
        Model.typeSchemeVariables = typeVars,
        Model.typeSchemeBody = (decoderTypeNamed ename typ),
        Model.typeSchemeConstraints = constraints}

-- | Filter bindings to only decodable type definitions
filterTypeBindings :: t0 -> Graph.Graph -> [Model.Binding] -> Either Errors.Error [Model.Binding]
filterTypeBindings cx graph bindings =
    Eithers.map Optionals.givens (Eithers.mapList (isDecodableBinding cx graph) (Lists.filter Annotations.isNativeType bindings))

-- | Check if a binding is decodable (serializable type)
isDecodableBinding :: t0 -> Graph.Graph -> Model.Binding -> Either Errors.Error (Maybe Model.Binding)
isDecodableBinding cx graph b =
    Eithers.bind (Predicates.isSerializableByName cx graph (Model.bindingName b)) (\serializable -> Right (Logic.ifElse serializable (Just b) Nothing))

-- | Prepend decoder types for forall parameters to base type
prependForallDecoders :: Model.Type -> Model.Type -> Model.Type
prependForallDecoders baseType typ =
    case typ of
      Model.TypeAnnotated v0 -> prependForallDecoders baseType (Model.annotatedTypeBody v0)
      Model.TypeForall v0 -> Model.TypeFunction (Model.FunctionType {
        Model.functionTypeDomain = (Model.TypeFunction (Model.FunctionType {
          Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.graph.Graph")),
          Model.functionTypeCodomain = (Model.TypeFunction (Model.FunctionType {
            Model.functionTypeDomain = (Model.TypeVariable (Model.Name "hydra.core.model.Term")),
            Model.functionTypeCodomain = (Model.TypeEither (Model.EitherType {
              Model.eitherTypeLeft = (Model.TypeVariable (Model.Name "hydra.core.errors.DecodingError")),
              Model.eitherTypeRight = (Model.TypeVariable (Model.forallTypeParameter v0))}))}))})),
        Model.functionTypeCodomain = (prependForallDecoders baseType (Model.forallTypeBody v0))})
      _ -> baseType

-- | Remove all leading forall quantifiers, returning the quantified body
stripForalls :: Model.Type -> Model.Type
stripForalls typ =
    case typ of
      Model.TypeAnnotated v0 -> stripForalls (Model.annotatedTypeBody v0)
      Model.TypeForall v0 -> stripForalls (Model.forallTypeBody v0)
      _ -> typ