packages feed

hydra-0.13.0: src/gen-main/haskell/Hydra/Extract/Core.hs

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

-- | Extraction and validation for hydra.core types

module Hydra.Extract.Core where

import qualified Hydra.Compute as Compute
import qualified Hydra.Core as Core
import qualified Hydra.Graph as Graph
import qualified Hydra.Lexical as Lexical
import qualified Hydra.Lib.Eithers as Eithers
import qualified Hydra.Lib.Equality as Equality
import qualified Hydra.Lib.Flows as Flows
import qualified Hydra.Lib.Lists as Lists
import qualified Hydra.Lib.Literals as Literals
import qualified Hydra.Lib.Logic as Logic
import qualified Hydra.Lib.Maps as Maps
import qualified Hydra.Lib.Maybes as Maybes
import qualified Hydra.Lib.Pairs as Pairs
import qualified Hydra.Lib.Strings as Strings
import qualified Hydra.Monads as Monads
import qualified Hydra.Rewriting as Rewriting
import qualified Hydra.Show.Core as Core_
import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
import qualified Data.ByteString as B
import qualified Data.Int as I
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S

-- | Extract an arbitrary-precision floating-point value from a term
bigfloat :: (Core.Term -> Compute.Flow Graph.Graph Double)
bigfloat t = (Flows.bind (literal t) (\l -> Flows.bind (floatLiteral l) (\f -> bigfloatValue f)))

-- | Extract a bigfloat value from a FloatValue
bigfloatValue :: (Core.FloatValue -> Compute.Flow t0 Double)
bigfloatValue v = ((\x -> case x of
  Core.FloatValueBigfloat v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "bigfloat" (Core_.float v))) v)

-- | Extract an arbitrary-precision integer value from a term
bigint :: (Core.Term -> Compute.Flow Graph.Graph Integer)
bigint t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> bigintValue i)))

-- | Extract a bigint value from an IntegerValue
bigintValue :: (Core.IntegerValue -> Compute.Flow t0 Integer)
bigintValue v = ((\x -> case x of
  Core.IntegerValueBigint v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "bigint" (Core_.integer v))) v)

-- | Extract a binary data value from a term
binary :: (Core.Term -> Compute.Flow Graph.Graph B.ByteString)
binary t = (Flows.bind (literal t) (\l -> binaryLiteral l))

-- | Extract a binary literal from a Literal value
binaryLiteral :: (Core.Literal -> Compute.Flow t0 B.ByteString)
binaryLiteral v = ((\x -> case x of
  Core.LiteralBinary v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "binary" (Core_.literal v))) v)

-- | Extract a boolean value from a term
boolean :: (Core.Term -> Compute.Flow Graph.Graph Bool)
boolean t = (Flows.bind (literal t) (\l -> booleanLiteral l))

-- | Extract a boolean literal from a Literal value
booleanLiteral :: (Core.Literal -> Compute.Flow t0 Bool)
booleanLiteral v = ((\x -> case x of
  Core.LiteralBoolean v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "boolean" (Core_.literal v))) v)

-- | Extract a specific case handler from a case statement term
caseField :: (Core.Name -> String -> Core.Term -> Compute.Flow Graph.Graph Core.Field)
caseField name n term =  
  let fieldName = (Core.Name n)
  in (Flows.bind (cases name term) (\cs ->  
    let matching = (Lists.filter (\f -> Equality.equal (Core.unName (Core.fieldName f)) (Core.unName fieldName)) (Core.caseStatementCases cs))
    in (Logic.ifElse (Lists.null matching) (Flows.fail "not enough cases") (Flows.pure (Lists.head matching)))))

-- | Extract case statement from a term
cases :: (Core.Name -> Core.Term -> Compute.Flow Graph.Graph Core.CaseStatement)
cases name term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermFunction v1 -> ((\x -> case x of
            Core.FunctionElimination v2 -> ((\x -> case x of
              Core.EliminationUnion v3 -> (Logic.ifElse (Equality.equal (Core.unName (Core.caseStatementTypeName v3)) (Core.unName name)) (Flows.pure v3) (Monads.unexpected (Strings.cat2 "case statement for type " (Core.unName name)) (Core_.term term)))
              _ -> (Monads.unexpected "case statement" (Core_.term term))) v2)
            _ -> (Monads.unexpected "case statement" (Core_.term term))) v1)
          _ -> (Monads.unexpected "case statement" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract a field value from a list of fields
field :: (Core.Name -> (Core.Term -> Compute.Flow Graph.Graph t0) -> [Core.Field] -> Compute.Flow Graph.Graph t0)
field fname mapping fields =  
  let matchingFields = (Lists.filter (\f -> Equality.equal (Core.unName (Core.fieldName f)) (Core.unName fname)) fields)
  in (Logic.ifElse (Lists.null matchingFields) (Flows.fail (Strings.cat2 (Strings.cat2 "field " (Core.unName fname)) " not found")) (Logic.ifElse (Equality.equal (Lists.length matchingFields) 1) (Flows.bind (Lexical.stripAndDereferenceTerm (Core.fieldTerm (Lists.head matchingFields))) (\stripped -> mapping stripped)) (Flows.fail (Strings.cat2 "multiple fields named " (Core.unName fname)))))

-- | Extract a 32-bit floating-point value from a term
float32 :: (Core.Term -> Compute.Flow Graph.Graph Float)
float32 t = (Flows.bind (literal t) (\l -> Flows.bind (floatLiteral l) (\f -> float32Value f)))

-- | Extract a float32 value from a FloatValue
float32Value :: (Core.FloatValue -> Compute.Flow t0 Float)
float32Value v = ((\x -> case x of
  Core.FloatValueFloat32 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "float32" (Core_.float v))) v)

-- | Extract a 64-bit floating-point value from a term
float64 :: (Core.Term -> Compute.Flow Graph.Graph Double)
float64 t = (Flows.bind (literal t) (\l -> Flows.bind (floatLiteral l) (\f -> float64Value f)))

-- | Extract a float64 value from a FloatValue
float64Value :: (Core.FloatValue -> Compute.Flow t0 Double)
float64Value v = ((\x -> case x of
  Core.FloatValueFloat64 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "float64" (Core_.float v))) v)

-- | Extract a floating-point literal from a Literal value
floatLiteral :: (Core.Literal -> Compute.Flow t0 Core.FloatValue)
floatLiteral lit = ((\x -> case x of
  Core.LiteralFloat v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "floating-point value" (Core_.literal lit))) lit)

-- | Extract a float value from a term
floatValue :: (Core.Term -> Compute.Flow Graph.Graph Core.FloatValue)
floatValue t = (Flows.bind (literal t) (\l -> floatLiteral l))

-- | Extract an either value from a term, applying functions to the left and right values
eitherTerm :: ((Core.Term -> Compute.Flow Graph.Graph t0) -> (Core.Term -> Compute.Flow Graph.Graph t1) -> Core.Term -> Compute.Flow Graph.Graph (Either t0 t1))
eitherTerm leftFun rightFun term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermEither v1 -> (Eithers.either (\l -> Flows.map (\x -> Left x) (leftFun l)) (\r -> Flows.map (\x -> Right x) (rightFun r)) v1)
          _ -> (Monads.unexpected "either value" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract the left and right types from an either type
eitherType :: (Core.Type -> Compute.Flow t0 Core.EitherType)
eitherType typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeEither v1 -> (Flows.pure v1)
    _ -> (Monads.unexpected "either type" (Core_.type_ typ))) stripped)

-- | Extract a function type from a type
functionType :: (Core.Type -> Compute.Flow t0 Core.FunctionType)
functionType typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeFunction v1 -> (Flows.pure v1)
    _ -> (Monads.unexpected "function type" (Core_.type_ typ))) stripped)

-- | Extract a field from a union term
injection :: (Core.Name -> Core.Term -> Compute.Flow Graph.Graph Core.Field)
injection expected term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermUnion v1 -> (Logic.ifElse (Equality.equal (Core.unName (Core.injectionTypeName v1)) (Core.unName expected)) (Flows.pure (Core.injectionField v1)) (Monads.unexpected (Strings.cat2 "injection of type " (Core.unName expected)) (Core.unName (Core.injectionTypeName v1))))
          _ -> (Monads.unexpected "injection" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract a 16-bit signed integer value from a term
int16 :: (Core.Term -> Compute.Flow Graph.Graph I.Int16)
int16 t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> int16Value i)))

-- | Extract an int16 value from an IntegerValue
int16Value :: (Core.IntegerValue -> Compute.Flow t0 I.Int16)
int16Value v = ((\x -> case x of
  Core.IntegerValueInt16 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "int16" (Core_.integer v))) v)

-- | Extract a 32-bit signed integer value from a term
int32 :: (Core.Term -> Compute.Flow Graph.Graph Int)
int32 t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> int32Value i)))

-- | Extract an int32 value from an IntegerValue
int32Value :: (Core.IntegerValue -> Compute.Flow t0 Int)
int32Value v = ((\x -> case x of
  Core.IntegerValueInt32 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "int32" (Core_.integer v))) v)

-- | Extract a 64-bit signed integer value from a term
int64 :: (Core.Term -> Compute.Flow Graph.Graph I.Int64)
int64 t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> int64Value i)))

-- | Extract an int64 value from an IntegerValue
int64Value :: (Core.IntegerValue -> Compute.Flow t0 I.Int64)
int64Value v = ((\x -> case x of
  Core.IntegerValueInt64 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "int64" (Core_.integer v))) v)

-- | Extract an 8-bit signed integer value from a term
int8 :: (Core.Term -> Compute.Flow Graph.Graph I.Int8)
int8 t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> int8Value i)))

-- | Extract an int8 value from an IntegerValue
int8Value :: (Core.IntegerValue -> Compute.Flow t0 I.Int8)
int8Value v = ((\x -> case x of
  Core.IntegerValueInt8 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "int8" (Core_.integer v))) v)

-- | Extract an integer literal from a Literal value
integerLiteral :: (Core.Literal -> Compute.Flow t0 Core.IntegerValue)
integerLiteral lit = ((\x -> case x of
  Core.LiteralInteger v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "integer value" (Core_.literal lit))) lit)

-- | Extract an integer value from a term
integerValue :: (Core.Term -> Compute.Flow Graph.Graph Core.IntegerValue)
integerValue t = (Flows.bind (literal t) (\l -> integerLiteral l))

-- | Extract the body of a lambda term
lambdaBody :: (Core.Term -> Compute.Flow Graph.Graph Core.Term)
lambdaBody term = (Flows.map Core.lambdaBody (lambda term))

-- | Extract a lambda from a term
lambda :: (Core.Term -> Compute.Flow Graph.Graph Core.Lambda)
lambda term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermFunction v1 -> ((\x -> case x of
            Core.FunctionLambda v2 -> (Flows.pure v2)
            _ -> (Monads.unexpected "lambda" (Core_.term term))) v1)
          _ -> (Monads.unexpected "lambda" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract a binding with the given name from a let term
letBinding :: (String -> Core.Term -> Compute.Flow Graph.Graph Core.Term)
letBinding n term =  
  let name = (Core.Name n)
  in (Flows.bind (let_ term) (\letExpr ->  
    let matchingBindings = (Lists.filter (\b -> Equality.equal (Core.unName (Core.bindingName b)) (Core.unName name)) (Core.letBindings letExpr))
    in (Logic.ifElse (Lists.null matchingBindings) (Flows.fail (Strings.cat2 "no such binding: " n)) (Logic.ifElse (Equality.equal (Lists.length matchingBindings) 1) (Flows.pure (Core.bindingTerm (Lists.head matchingBindings))) (Flows.fail (Strings.cat2 "multiple bindings named " n))))))

-- | Extract a let expression from a term
let_ :: (Core.Term -> Compute.Flow Graph.Graph Core.Let)
let_ term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermLet v1 -> (Flows.pure v1)
          _ -> (Monads.unexpected "let term" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract a list of terms from a term
list :: (Core.Term -> Compute.Flow Graph.Graph [Core.Term])
list term =  
  let extract = (\stripped -> (\x -> case x of
          Core.TermList v1 -> (Flows.pure v1)
          _ -> (Monads.unexpected "list" (Core_.term stripped))) stripped)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term) (\stripped -> extract stripped))

-- | Extract the first element of a list term
listHead :: (Core.Term -> Compute.Flow Graph.Graph Core.Term)
listHead term = (Flows.bind (list term) (\l -> Logic.ifElse (Lists.null l) (Flows.fail "empty list") (Flows.pure (Lists.head l))))

-- | Extract a list of values from a term, mapping a function over each element
listOf :: ((Core.Term -> Compute.Flow Graph.Graph t0) -> Core.Term -> Compute.Flow Graph.Graph [t0])
listOf f term = (Flows.bind (list term) (\els -> Flows.mapList f els))

-- | Extract the element type from a list type
listType :: (Core.Type -> Compute.Flow t0 Core.Type)
listType typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeList v1 -> (Flows.pure v1)
    _ -> (Monads.unexpected "list type" (Core_.type_ typ))) stripped)

-- | Extract a literal value from a term
literal :: (Core.Term -> Compute.Flow Graph.Graph Core.Literal)
literal term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermLiteral v1 -> (Flows.pure v1)
          _ -> (Monads.unexpected "literal" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract a map of key-value pairs from a term, mapping functions over each key and value
map :: Ord t0 => ((Core.Term -> Compute.Flow Graph.Graph t0) -> (Core.Term -> Compute.Flow Graph.Graph t1) -> Core.Term -> Compute.Flow Graph.Graph (M.Map t0 t1))
map fk fv term0 =  
  let pair = (\kvPair ->  
          let kterm = (Pairs.first kvPair)
          in  
            let vterm = (Pairs.second kvPair)
            in (Flows.bind (fk kterm) (\kval -> Flows.bind (fv vterm) (\vval -> Flows.pure (kval, vval)))))
  in  
    let extract = (\term -> (\x -> case x of
            Core.TermMap v1 -> (Flows.map Maps.fromList (Flows.mapList pair (Maps.toList v1)))
            _ -> (Monads.unexpected "map" (Core_.term term))) term)
    in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract the key and value types from a map type
mapType :: (Core.Type -> Compute.Flow t0 Core.MapType)
mapType typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeMap v1 -> (Flows.pure v1)
    _ -> (Monads.unexpected "map type" (Core_.type_ typ))) stripped)

-- | Ensure a function has the expected number of arguments
nArgs :: (Core.Name -> Int -> [t0] -> Compute.Flow t1 ())
nArgs name n args = (Logic.ifElse (Equality.equal (Lists.length args) n) (Flows.pure ()) (Monads.unexpected (Strings.cat [
  Literals.showInt32 n,
  " arguments to primitive ",
  (Literals.showString (Core.unName name))]) (Literals.showInt32 (Lists.length args))))

-- | Extract an optional value from a term, applying a function to the value if present
maybeTerm :: ((Core.Term -> Compute.Flow Graph.Graph t0) -> Core.Term -> Compute.Flow Graph.Graph (Maybe t0))
maybeTerm f term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermMaybe v1 -> (Maybes.maybe (Flows.pure Nothing) (\t -> Flows.map Maybes.pure (f t)) v1)
          _ -> (Monads.unexpected "maybe value" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract the base type from an optional type
maybeType :: (Core.Type -> Compute.Flow t0 Core.Type)
maybeType typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeMaybe v1 -> (Flows.pure v1)
    _ -> (Monads.unexpected "maybe type" (Core_.type_ typ))) stripped)

-- | Extract a pair of values from a term, applying functions to each component
pair :: ((Core.Term -> Compute.Flow Graph.Graph t0) -> (Core.Term -> Compute.Flow Graph.Graph t1) -> Core.Term -> Compute.Flow Graph.Graph (t0, t1))
pair kf vf term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermPair v1 -> (Flows.bind (kf (Pairs.first v1)) (\kVal -> Flows.bind (vf (Pairs.second v1)) (\vVal -> Flows.pure (kVal, vVal))))
          _ -> (Monads.unexpected "pair" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract a record's fields from a term
record :: (Core.Name -> Core.Term -> Compute.Flow Graph.Graph [Core.Field])
record expected term0 = (Flows.bind (termRecord term0) (\record -> Logic.ifElse (Equality.equal (Core.recordTypeName record) expected) (Flows.pure (Core.recordFields record)) (Monads.unexpected (Strings.cat2 "record of type " (Core.unName expected)) (Core.unName (Core.recordTypeName record)))))

-- | Extract the field types from a record type
recordType :: (Core.Name -> Core.Type -> Compute.Flow t0 [Core.FieldType])
recordType ename typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeRecord v1 -> (Logic.ifElse (Equality.equal (Core.unName (Core.rowTypeTypeName v1)) (Core.unName ename)) (Flows.pure (Core.rowTypeFields v1)) (Monads.unexpected (Strings.cat2 "record of type " (Core.unName ename)) (Strings.cat2 "record of type " (Core.unName (Core.rowTypeTypeName v1)))))
    _ -> (Monads.unexpected "record type" (Core_.type_ typ))) stripped)

-- | Extract a set of terms from a term
set :: (Core.Term -> Compute.Flow Graph.Graph (S.Set Core.Term))
set term =  
  let extract = (\stripped -> (\x -> case x of
          Core.TermSet v1 -> (Flows.pure v1)
          _ -> (Monads.unexpected "set" (Core_.term stripped))) stripped)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term) (\stripped -> extract stripped))

-- | Extract a set of values from a term, mapping a function over each element
setOf :: Ord t0 => ((Core.Term -> Compute.Flow Graph.Graph t0) -> Core.Term -> Compute.Flow Graph.Graph (S.Set t0))
setOf f term = (Flows.bind (set term) (\els -> Flows.mapSet f els))

-- | Extract the element type from a set type
setType :: (Core.Type -> Compute.Flow t0 Core.Type)
setType typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeSet v1 -> (Flows.pure v1)
    _ -> (Monads.unexpected "set type" (Core_.type_ typ))) stripped)

-- | Extract a string value from a term
string :: (Core.Term -> Compute.Flow Graph.Graph String)
string t = (Flows.bind (literal t) (\l -> stringLiteral l))

-- | Extract a string literal from a Literal value
stringLiteral :: (Core.Literal -> Compute.Flow t0 String)
stringLiteral v = ((\x -> case x of
  Core.LiteralString v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "string" (Core_.literal v))) v)

-- | Extract a record from a term
termRecord :: (Core.Term -> Compute.Flow Graph.Graph Core.Record)
termRecord term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermRecord v1 -> (Flows.pure v1)
          _ -> (Monads.unexpected "record" (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract a 16-bit unsigned integer value from a term
uint16 :: (Core.Term -> Compute.Flow Graph.Graph Int)
uint16 t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> uint16Value i)))

-- | Extract a uint16 value from an IntegerValue
uint16Value :: (Core.IntegerValue -> Compute.Flow t0 Int)
uint16Value v = ((\x -> case x of
  Core.IntegerValueUint16 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "uint16" (Core_.integer v))) v)

-- | Extract a 32-bit unsigned integer value from a term
uint32 :: (Core.Term -> Compute.Flow Graph.Graph I.Int64)
uint32 t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> uint32Value i)))

-- | Extract a uint32 value from an IntegerValue
uint32Value :: (Core.IntegerValue -> Compute.Flow t0 I.Int64)
uint32Value v = ((\x -> case x of
  Core.IntegerValueUint32 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "uint32" (Core_.integer v))) v)

-- | Extract a 64-bit unsigned integer value from a term
uint64 :: (Core.Term -> Compute.Flow Graph.Graph Integer)
uint64 t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> uint64Value i)))

-- | Extract a uint64 value from an IntegerValue
uint64Value :: (Core.IntegerValue -> Compute.Flow t0 Integer)
uint64Value v = ((\x -> case x of
  Core.IntegerValueUint64 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "uint64" (Core_.integer v))) v)

-- | Extract an 8-bit unsigned integer value from a term
uint8 :: (Core.Term -> Compute.Flow Graph.Graph I.Int16)
uint8 t = (Flows.bind (literal t) (\l -> Flows.bind (integerLiteral l) (\i -> uint8Value i)))

-- | Extract a uint8 value from an IntegerValue
uint8Value :: (Core.IntegerValue -> Compute.Flow t0 I.Int16)
uint8Value v = ((\x -> case x of
  Core.IntegerValueUint8 v1 -> (Flows.pure v1)
  _ -> (Monads.unexpected "uint8" (Core_.integer v))) v)

-- | Extract the field types from a union type
unionType :: (Core.Name -> Core.Type -> Compute.Flow t0 [Core.FieldType])
unionType ename typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeUnion v1 -> (Logic.ifElse (Equality.equal (Core.rowTypeTypeName v1) ename) (Flows.pure (Core.rowTypeFields v1)) (Monads.unexpected (Strings.cat2 "union of type " (Core.unName ename)) (Strings.cat2 "union of type " (Core.unName (Core.rowTypeTypeName v1)))))
    _ -> (Monads.unexpected "union type" (Core_.type_ typ))) stripped)

-- | Extract a unit value from a term
unit :: (Core.Term -> Compute.Flow t0 ())
unit term = ((\x -> case x of
  Core.TermUnit -> (Flows.pure ())
  _ -> (Monads.unexpected "unit" (Core_.term term))) term)

-- | Extract a unit variant (a variant with an empty record value) from a union term
unitVariant :: (Core.Name -> Core.Term -> Compute.Flow Graph.Graph Core.Name)
unitVariant tname term = (Flows.bind (injection tname term) (\field -> Flows.bind (unit (Core.fieldTerm field)) (\ignored -> Flows.pure (Core.fieldName field))))

-- | Extract the wrapped value from a wrapped term
wrap :: (Core.Name -> Core.Term -> Compute.Flow Graph.Graph Core.Term)
wrap expected term0 =  
  let extract = (\term -> (\x -> case x of
          Core.TermWrap v1 -> (Logic.ifElse (Equality.equal (Core.unName (Core.wrappedTermTypeName v1)) (Core.unName expected)) (Flows.pure (Core.wrappedTermBody v1)) (Monads.unexpected (Strings.cat2 "wrapper of type " (Core.unName expected)) (Core.unName (Core.wrappedTermTypeName v1))))
          _ -> (Monads.unexpected (Strings.cat2 (Strings.cat2 "wrap(" (Core.unName expected)) ")") (Core_.term term))) term)
  in (Flows.bind (Lexical.stripAndDereferenceTerm term0) (\term -> extract term))

-- | Extract the wrapped type from a wrapper type
wrappedType :: (Core.Name -> Core.Type -> Compute.Flow t0 Core.Type)
wrappedType ename typ =  
  let stripped = (Rewriting.deannotateType typ)
  in ((\x -> case x of
    Core.TypeWrap v1 -> (Logic.ifElse (Equality.equal (Core.unName (Core.wrappedTypeTypeName v1)) (Core.unName ename)) (Flows.pure (Core.wrappedTypeBody v1)) (Monads.unexpected (Strings.cat2 "wrapped type " (Core.unName ename)) (Strings.cat2 "wrapped type " (Core.unName (Core.wrappedTypeTypeName v1)))))
    _ -> (Monads.unexpected "wrapped type" (Core_.type_ typ))) stripped)