hydra-kernel-0.16.0: src/main/haskell/Hydra/Scoping.hs
-- Note: this is an automatically generated file. Do not edit.
-- | Graph context extension and type scheme conversion
module Hydra.Scoping where
import qualified Hydra.Ast as Ast
import qualified Hydra.Coders as Coders
import qualified Hydra.Core as Core
import qualified Hydra.Error.Checking as Checking
import qualified Hydra.Error.Core as ErrorCore
import qualified Hydra.Error.Packaging as ErrorPackaging
import qualified Hydra.Errors as Errors
import qualified Hydra.Graph as Graph
import qualified Hydra.Json.Model as Model
import qualified Hydra.Haskell.Lib.Lists as Lists
import qualified Hydra.Haskell.Lib.Literals as Literals
import qualified Hydra.Haskell.Lib.Logic as Logic
import qualified Hydra.Haskell.Lib.Maps as Maps
import qualified Hydra.Haskell.Lib.Math as Math
import qualified Hydra.Haskell.Lib.Optionals as Optionals
import qualified Hydra.Haskell.Lib.Pairs as Pairs
import qualified Hydra.Haskell.Lib.Sets as Sets
import qualified Hydra.Haskell.Lib.Strings as Strings
import qualified Hydra.Packaging as Packaging
import qualified Hydra.Parsing as Parsing
import qualified Hydra.Paths as Paths
import qualified Hydra.Query as Query
import qualified Hydra.Relational as Relational
import qualified Hydra.Tabular as Tabular
import qualified Hydra.Testing as Testing
import qualified Hydra.Topology as Topology
import qualified Hydra.Typed as Typed
import qualified Hydra.Typing as Typing
import qualified Hydra.Util as Util
import qualified Hydra.Validation as Validation
import qualified Hydra.Variants as Variants
import Prelude hiding (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
import qualified Data.Scientific as Sci
-- | Extend a graph by descending into a lambda body
extendGraphForLambda :: Graph.Graph -> Core.Lambda -> Graph.Graph
extendGraphForLambda g lam =
let var = Core.lambdaParameter lam
in Graph.Graph {
Graph.graphBoundTerms = (Graph.graphBoundTerms g),
Graph.graphBoundTypes = (Optionals.cases (Core.lambdaDomain lam) (Graph.graphBoundTypes g) (\dom -> Maps.insert var (fTypeToTypeScheme dom) (Graph.graphBoundTypes g))),
Graph.graphClassConstraints = (Graph.graphClassConstraints g),
Graph.graphLambdaVariables = (Sets.insert var (Graph.graphLambdaVariables g)),
Graph.graphMetadata = (Maps.delete var (Graph.graphMetadata g)),
Graph.graphPrimitives = (Graph.graphPrimitives g),
Graph.graphSchemaTypes = (Graph.graphSchemaTypes g),
Graph.graphTypeVariables = (Graph.graphTypeVariables g)}
-- | Extend a graph by descending into a let body
extendGraphForLet :: (Graph.Graph -> Core.Binding -> Maybe Core.Term) -> Graph.Graph -> Core.Let -> Graph.Graph
extendGraphForLet forBinding g letrec =
let bindings = Core.letBindings letrec
g2 = extendGraphWithBindings bindings g
in Graph.Graph {
Graph.graphBoundTerms = (Maps.union (Maps.fromList (Lists.map (\b -> (Core.bindingName b, (Core.bindingTerm b))) bindings)) (Graph.graphBoundTerms g)),
Graph.graphBoundTypes = (Maps.union (Maps.fromList (Optionals.cat (Lists.map (\b -> Optionals.map (\ts -> (Core.bindingName b, ts)) (Core.bindingTypeScheme b)) bindings))) (Graph.graphBoundTypes g)),
Graph.graphClassConstraints = (Graph.graphClassConstraints g),
Graph.graphLambdaVariables = (Lists.foldl (\s -> \b -> Sets.delete (Core.bindingName b) s) (Graph.graphLambdaVariables g) bindings),
Graph.graphMetadata = (Graph.graphMetadata (Lists.foldl (\gAcc -> \b ->
let m = Graph.graphMetadata gAcc
newMeta = Optionals.cases (forBinding gAcc b) (Maps.delete (Core.bindingName b) m) (\t -> Maps.insert (Core.bindingName b) t m)
in Graph.Graph {
Graph.graphBoundTerms = (Graph.graphBoundTerms gAcc),
Graph.graphBoundTypes = (Graph.graphBoundTypes gAcc),
Graph.graphClassConstraints = (Graph.graphClassConstraints gAcc),
Graph.graphLambdaVariables = (Graph.graphLambdaVariables gAcc),
Graph.graphMetadata = newMeta,
Graph.graphPrimitives = (Graph.graphPrimitives gAcc),
Graph.graphSchemaTypes = (Graph.graphSchemaTypes gAcc),
Graph.graphTypeVariables = (Graph.graphTypeVariables gAcc)}) g2 bindings)),
Graph.graphPrimitives = (Graph.graphPrimitives g),
Graph.graphSchemaTypes = (Graph.graphSchemaTypes g),
Graph.graphTypeVariables = (Graph.graphTypeVariables g)}
-- | Extend a graph by descending into a type lambda body
extendGraphForTypeLambda :: Graph.Graph -> Core.TypeLambda -> Graph.Graph
extendGraphForTypeLambda g tlam =
let name = Core.typeLambdaParameter tlam
in Graph.Graph {
Graph.graphBoundTerms = (Graph.graphBoundTerms g),
Graph.graphBoundTypes = (Graph.graphBoundTypes g),
Graph.graphClassConstraints = (Graph.graphClassConstraints g),
Graph.graphLambdaVariables = (Graph.graphLambdaVariables g),
Graph.graphMetadata = (Graph.graphMetadata g),
Graph.graphPrimitives = (Graph.graphPrimitives g),
Graph.graphSchemaTypes = (Graph.graphSchemaTypes g),
Graph.graphTypeVariables = (Sets.insert name (Graph.graphTypeVariables g))}
-- | Add bindings to an existing graph
extendGraphWithBindings :: [Core.Binding] -> Graph.Graph -> Graph.Graph
extendGraphWithBindings bindings g =
let newTerms = Maps.fromList (Lists.map (\b -> (Core.bindingName b, (Core.bindingTerm b))) bindings)
newTypes =
Maps.fromList (Optionals.cat (Lists.map (\b -> Optionals.map (\ts -> (Core.bindingName b, ts)) (Core.bindingTypeScheme b)) bindings))
in Graph.Graph {
Graph.graphBoundTerms = (Maps.union newTerms (Graph.graphBoundTerms g)),
Graph.graphBoundTypes = (Maps.union newTypes (Graph.graphBoundTypes g)),
Graph.graphClassConstraints = (Graph.graphClassConstraints g),
Graph.graphLambdaVariables = (Graph.graphLambdaVariables g),
Graph.graphMetadata = (Graph.graphMetadata g),
Graph.graphPrimitives = (Graph.graphPrimitives g),
Graph.graphSchemaTypes = (Graph.graphSchemaTypes g),
Graph.graphTypeVariables = (Graph.graphTypeVariables g)}
-- | Convert a forall type to a type scheme
fTypeToTypeScheme :: Core.Type -> Core.TypeScheme
fTypeToTypeScheme typ =
let stripAnnotations =
\t -> case t of
Core.TypeAnnotated v0 -> stripAnnotations (Core.annotatedTypeBody v0)
_ -> t
gatherForall =
\vars -> \typ2 -> case (stripAnnotations typ2) of
Core.TypeForall v0 -> gatherForall (Lists.cons (Core.forallTypeParameter v0) vars) (Core.forallTypeBody v0)
_ -> Core.TypeScheme {
Core.typeSchemeVariables = (Lists.reverse vars),
Core.typeSchemeBody = typ2,
Core.typeSchemeConstraints = Nothing}
in (gatherForall [] typ)
-- | Convert a TermSignature to a TypeScheme, erasing parameter names, descriptions, and laziness flags.
termSignatureToTypeScheme :: Typing.TermSignature -> Core.TypeScheme
termSignatureToTypeScheme sig =
let typeParams = Typing.termSignatureTypeParameters sig
params = Typing.termSignatureParameters sig
result = Typing.termSignatureResult sig
variables = Lists.map (\tp -> Typing.typeParameterName tp) typeParams
body =
Lists.foldl (\acc -> \p -> Core.TypeFunction (Core.FunctionType {
Core.functionTypeDomain = (Typing.parameterType p),
Core.functionTypeCodomain = acc})) (Typing.resultType result) (Lists.reverse params)
hasConstraints =
Lists.foldl (\acc -> \tp -> Logic.or acc (Logic.not (Lists.null (Typing.typeParameterConstraints tp)))) False typeParams
constraints =
Logic.ifElse hasConstraints (Just (Maps.fromList (Lists.map (\tp -> (
Typing.typeParameterName tp,
Core.TypeVariableConstraints {
Core.typeVariableConstraintsClasses = (Typing.typeParameterConstraints tp)})) typeParams))) Nothing
in Core.TypeScheme {
Core.typeSchemeVariables = variables,
Core.typeSchemeBody = body,
Core.typeSchemeConstraints = constraints}
-- | Convert a type scheme to a forall type
typeSchemeToFType :: Core.TypeScheme -> Core.Type
typeSchemeToFType ts =
let vars = Core.typeSchemeVariables ts
body = Core.typeSchemeBody ts
in (Lists.foldl (\t -> \v -> Core.TypeForall (Core.ForallType {
Core.forallTypeParameter = v,
Core.forallTypeBody = t})) body (Lists.reverse vars))
-- | Convert a TypeScheme to a TermSignature. Type variables and class constraints are preserved exactly. Value-parameter names are synthesized as arg0, arg1, .... Per-parameter descriptions are nothing and isLazy defaults to false.
typeSchemeToTermSignature :: Core.TypeScheme -> Typing.TermSignature
typeSchemeToTermSignature ts =
let variables = Core.typeSchemeVariables ts
body = Core.typeSchemeBody ts
constraintsMap = Optionals.fromOptional Maps.empty (Core.typeSchemeConstraints ts)
typeParams =
Lists.map (\v -> Typing.TypeParameter {
Typing.typeParameterName = v,
Typing.typeParameterConstraints = (Optionals.cases (Maps.lookup v constraintsMap) [] (\tvm -> Core.typeVariableConstraintsClasses tvm))}) variables
peel =
\acc -> \t -> case t of
Core.TypeFunction v0 -> peel (Lists.cons (Core.functionTypeDomain v0) acc) (Core.functionTypeCodomain v0)
_ -> (Lists.reverse acc, t)
peeled = peel [] body
paramTypes = Pairs.first peeled
resultType = Pairs.second peeled
params =
Lists.reverse (Pairs.first (Lists.foldl (\acc -> \ty ->
let pairAcc = Pairs.first acc
i = Pairs.second acc
in (
Lists.cons (Typing.Parameter {
Typing.parameterName = (Core.Name (Strings.cat [
"arg",
(Literals.showInt32 i)])),
Typing.parameterDescription = Nothing,
Typing.parameterType = ty,
Typing.parameterIsLazy = False}) pairAcc,
(Math.add i 1))) ([], 0) paramTypes))
result =
Typing.Result {
Typing.resultDescription = Nothing,
Typing.resultType = resultType}
in Typing.TermSignature {
Typing.termSignatureTypeParameters = typeParams,
Typing.termSignatureParameters = params,
Typing.termSignatureResult = result}