module Hydra.Types.Inference (
annotateElementWithTypes,
annotateTermWithTypes,
inferType,
Constraint,
) where
import Hydra.All
import Hydra.CoreDecoding
import Hydra.CoreEncoding
import qualified Hydra.Impl.Haskell.Dsl.Types as Types
import Hydra.Types.Substitution
import Hydra.Types.Unification
import qualified Control.Monad as CM
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Maybe as Y
type InferenceContext m = (Context m, Int, TypingEnvironment m)
type TypingEnvironment m = M.Map Variable (TypeScheme m)
annotateElementWithTypes :: (Ord m, Show m) => Element m -> GraphFlow m (Element m)
annotateElementWithTypes :: forall m. (Ord m, Show m) => Element m -> GraphFlow m (Element m)
annotateElementWithTypes Element m
el = do
forall s a. String -> Flow s a -> Flow s a
withTrace (String
"annotate element " forall a. [a] -> [a] -> [a]
++ Name -> String
unName (forall m. Element m -> Name
elementName Element m
el)) forall a b. (a -> b) -> a -> b
$ do
Term m
term <- forall m. (Ord m, Show m) => Term m -> GraphFlow m (Term m)
annotateTermWithTypes forall a b. (a -> b) -> a -> b
$ forall m. Element m -> Term m
elementData Element m
el
Type m
typ <- forall {m}. Term m -> Flow (Context m) (Type m)
findType Term m
term
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Element m
el {
elementData :: Term m
elementData = Term m
term,
elementSchema :: Term m
elementSchema = forall m. Type m -> Term m
encodeType Type m
typ}
where
findType :: Term m -> Flow (Context m) (Type m)
findType Term m
term = do
Context m
cx <- forall s. Flow s s
getState
Maybe (Type m)
mt <- forall m.
AnnotationClass m -> Term m -> Flow (Context m) (Maybe (Type m))
annotationClassTermType (forall m. Context m -> AnnotationClass m
contextAnnotations Context m
cx) Term m
term
case Maybe (Type m)
mt of
Just Type m
t -> forall (m :: * -> *) a. Monad m => a -> m a
return Type m
t
Maybe (Type m)
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expected a type annotation"
annotateTermWithTypes :: (Ord m, Show m) => Term m -> GraphFlow m (Term m)
annotateTermWithTypes :: forall m. (Ord m, Show m) => Term m -> GraphFlow m (Term m)
annotateTermWithTypes Term m
term0 = do
(Term (m, Type m, [Constraint m])
term1, TypeScheme m
_) <- forall m.
(Ord m, Show m) =>
Term m
-> GraphFlow m (Term (m, Type m, [Constraint m]), TypeScheme m)
inferType Term m
term0
AnnotationClass m
anns <- forall m. Context m -> AnnotationClass m
contextAnnotations forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s. Flow s s
getState
Maybe (Type m)
mt <- forall m.
AnnotationClass m -> Term m -> Flow (Context m) (Maybe (Type m))
annotationClassTermType AnnotationClass m
anns Term m
term0
let annotType :: (m, Type m, c) -> m
annotType (m
ann, Type m
typ, c
_) = forall m. AnnotationClass m -> Maybe (Type m) -> m -> m
annotationClassSetTypeOf AnnotationClass m
anns (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
Y.fromMaybe Type m
typ Maybe (Type m)
mt) m
ann
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall b a. Ord b => (a -> b) -> Term a -> Term b
rewriteTermMeta forall {c}. (m, Type m, c) -> m
annotType Term (m, Type m, [Constraint m])
term1
decodeStructuralType :: Show m => Term m -> GraphFlow m (Type m)
decodeStructuralType :: forall m. Show m => Term m -> GraphFlow m (Type m)
decodeStructuralType Term m
term = do
Type m
typ <- forall m. Show m => Term m -> GraphFlow m (Type m)
decodeType Term m
term
let typ' :: Type m
typ' = forall m. Type m -> Type m
stripType Type m
typ
case Type m
typ' of
TypeNominal Name
name -> forall m a. GraphFlow m a -> GraphFlow m a
withSchemaContext forall a b. (a -> b) -> a -> b
$ forall s a. String -> Flow s a -> Flow s a
withTrace String
"decode structural type" forall a b. (a -> b) -> a -> b
$ do
Element m
el <- forall m. Name -> GraphFlow m (Element m)
requireElement Name
name
forall m. Show m => Term m -> GraphFlow m (Type m)
decodeStructuralType forall a b. (a -> b) -> a -> b
$ forall m. Element m -> Term m
elementData Element m
el
Type m
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Type m
typ
freshVariableType :: Flow (InferenceContext m) (Type m)
freshVariableType :: forall m. Flow (InferenceContext m) (Type m)
freshVariableType = do
(Context m
cx, Int
s, TypingEnvironment m
e) <- forall s. Flow s s
getState
forall s. s -> Flow s ()
putState (Context m
cx, Int
s forall a. Num a => a -> a -> a
+ Int
1, TypingEnvironment m
e)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall m. String -> Type m
Types.variable (VariableType -> String
unVariableType forall a b. (a -> b) -> a -> b
$ [VariableType]
normalVariables forall a. [a] -> Int -> a
!! Int
s)
generalize :: Show m => TypingEnvironment m -> Type m -> TypeScheme m
generalize :: forall m. Show m => TypingEnvironment m -> Type m -> TypeScheme m
generalize TypingEnvironment m
env Type m
t = forall m. [VariableType] -> Type m -> TypeScheme m
TypeScheme [VariableType]
vars Type m
t
where
vars :: [VariableType]
vars = forall a. Set a -> [a]
S.toList forall a b. (a -> b) -> a -> b
$ forall a. Ord a => Set a -> Set a -> Set a
S.difference
(forall m. Type m -> Set VariableType
freeVariablesInType Type m
t)
(forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
L.foldr (forall a. Ord a => Set a -> Set a -> Set a
S.union forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m. Show m => TypeScheme m -> Set VariableType
freeVariablesInScheme) forall a. Set a
S.empty forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [a]
M.elems TypingEnvironment m
env)
extendEnvironment :: Variable -> TypeScheme m -> Flow (InferenceContext m) a -> Flow (InferenceContext m) a
extendEnvironment :: forall m a.
Variable
-> TypeScheme m
-> Flow (InferenceContext m) a
-> Flow (InferenceContext m) a
extendEnvironment Variable
x TypeScheme m
sc = forall m a.
(TypingEnvironment m -> TypingEnvironment m)
-> Flow (InferenceContext m) a -> Flow (InferenceContext m) a
withEnvironment (\TypingEnvironment m
e -> forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Variable
x TypeScheme m
sc forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> Map k a -> Map k a
M.delete Variable
x TypingEnvironment m
e)
findMatchingField :: Show m => FieldName -> [FieldType m] -> Flow (InferenceContext m) (FieldType m)
findMatchingField :: forall m.
Show m =>
FieldName
-> [FieldType m] -> Flow (InferenceContext m) (FieldType m)
findMatchingField FieldName
fname [FieldType m]
sfields = case forall a. (a -> Bool) -> [a] -> [a]
L.filter (\FieldType m
f -> forall m. FieldType m -> FieldName
fieldTypeName FieldType m
f forall a. Eq a => a -> a -> Bool
== FieldName
fname) [FieldType m]
sfields of
[] -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"no such field: " forall a. [a] -> [a] -> [a]
++ FieldName -> String
unFieldName FieldName
fname
(FieldType m
h:[FieldType m]
_) -> forall (m :: * -> *) a. Monad m => a -> m a
return FieldType m
h
infer :: (Ord m, Show m) => Term m -> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer :: forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
term = do
(Context m
cx, Int
_, TypingEnvironment m
_) <- forall s. Flow s s
getState
Maybe (Type m)
mt <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m.
AnnotationClass m -> Term m -> Flow (Context m) (Maybe (Type m))
annotationClassTermType (forall m. Context m -> AnnotationClass m
contextAnnotations Context m
cx) Term m
term
case Maybe (Type m)
mt of
Just Type m
typ -> do
Term (m, Type m, [Constraint m])
i <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
inferInternal Term m
term
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall m. Annotated (Term m) m -> Term m
TermAnnotated forall a b. (a -> b) -> a -> b
$ forall a m. a -> m -> Annotated a m
Annotated Term (m, Type m, [Constraint m])
i (forall m. Context m -> Term m -> m
termMeta Context m
cx Term m
term, Type m
typ, [])
Maybe (Type m)
Nothing -> forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
inferInternal Term m
term
inferInternal :: (Ord m, Show m) => Term m -> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
inferInternal :: forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
inferInternal Term m
term = case Term m
term of
TermAnnotated (Annotated Term m
term1 m
ann) -> do
Term (m, Type m, [Constraint m])
iterm <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
term1
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Term (m, Type m, [Constraint m])
iterm of
TermAnnotated (Annotated Term (m, Type m, [Constraint m])
trm (m
_, Type m
t, [Constraint m]
c)) -> forall m. Annotated (Term m) m -> Term m
TermAnnotated (forall a m. a -> m -> Annotated a m
Annotated Term (m, Type m, [Constraint m])
trm (m
ann, Type m
t, [Constraint m]
c))
TermApplication (Application Term m
fun Term m
arg) -> do
Term (m, Type m, [Constraint m])
ifun <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
fun
Term (m, Type m, [Constraint m])
iarg <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
arg
Type m
v <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
let c :: [Constraint m]
c = (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
ifun) forall a. [a] -> [a] -> [a]
++ (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
iarg) forall a. [a] -> [a] -> [a]
++ [(forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
ifun, forall m. Type m -> Type m -> Type m
Types.function (forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
iarg) Type m
v)]
let app :: Term (m, Type m, [Constraint m])
app = forall m. Application m -> Term m
TermApplication forall a b. (a -> b) -> a -> b
$ forall m. Term m -> Term m -> Application m
Application Term (m, Type m, [Constraint m])
ifun Term (m, Type m, [Constraint m])
iarg
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield Term (m, Type m, [Constraint m])
app Type m
v [Constraint m]
c
TermElement Name
name -> do
Type m
et <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. Show m => Name -> GraphFlow m (Type m)
typeOfElement Name
name
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Name -> Term m
TermElement Name
name) (forall m. Type m -> Type m
Types.element Type m
et) []
TermFunction Function m
f -> case Function m
f of
FunctionCompareTo Term m
other -> do
Term (m, Type m, [Constraint m])
i <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
other
forall {a} {b} {c} {b} {c}.
Function (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldFunction (forall m. Term m -> Function m
FunctionCompareTo Term (m, Type m, [Constraint m])
i) (forall m. Type m -> Type m -> Type m
Types.function (forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
i) forall m. Type m
Types.int8) (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
i)
FunctionElimination Elimination m
e -> case Elimination m
e of
Elimination m
EliminationElement -> do
Type m
et <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
forall {a} {b} {c} {b} {c}.
Elimination (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldElimination forall m. Elimination m
EliminationElement (forall m. Type m -> Type m -> Type m
Types.function (forall m. Type m -> Type m
Types.element Type m
et) Type m
et) []
EliminationList Term m
fun -> do
Type m
a <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
Type m
b <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
let expected :: Type m
expected = forall m. [Type m] -> Type m -> Type m
Types.functionN [Type m
b, Type m
a] Type m
b
Term (m, Type m, [Constraint m])
i <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
fun
let elim :: Type m
elim = forall m. [Type m] -> Type m -> Type m
Types.functionN [Type m
b, forall m. Type m -> Type m
Types.list Type m
a] Type m
b
forall {a} {b} {c} {b} {c}.
Elimination (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldElimination (forall m. Term m -> Elimination m
EliminationList Term (m, Type m, [Constraint m])
i) Type m
elim [(Type m
expected, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
i)]
EliminationNominal Name
name -> do
Type m
typ <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. Show m => String -> Name -> GraphFlow m (Type m)
namedType String
"eliminate nominal" Name
name
forall {a} {b} {c} {b} {c}.
Elimination (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldElimination (forall m. Name -> Elimination m
EliminationNominal Name
name) (forall m. Type m -> Type m -> Type m
Types.function (forall m. Name -> Type m
Types.nominal Name
name) Type m
typ) []
EliminationOptional (OptionalCases Term m
n Term m
j) -> do
Type m
dom <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
Type m
cod <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
Term (m, Type m, [Constraint m])
ni <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
n
Term (m, Type m, [Constraint m])
ji <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
j
let t :: Type m
t = forall m. Type m -> Type m -> Type m
Types.function (forall m. Type m -> Type m
Types.optional Type m
dom) Type m
cod
let constraints :: [Constraint m]
constraints = [(Type m
cod, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
ni), (forall m. Type m -> Type m -> Type m
Types.function Type m
dom Type m
cod, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
ji)]
forall {a} {b} {c} {b} {c}.
Elimination (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldElimination (forall m. OptionalCases m -> Elimination m
EliminationOptional forall a b. (a -> b) -> a -> b
$ forall m. Term m -> Term m -> OptionalCases m
OptionalCases Term (m, Type m, [Constraint m])
ni Term (m, Type m, [Constraint m])
ji) Type m
t [Constraint m]
constraints
EliminationRecord (Projection Name
name FieldName
fname) -> do
RowType m
rt <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. Show m => Bool -> Name -> GraphFlow m (RowType m)
requireRecordType Bool
True Name
name
FieldType m
sfield <- forall m.
Show m =>
FieldName
-> [FieldType m] -> Flow (InferenceContext m) (FieldType m)
findMatchingField FieldName
fname (forall m. RowType m -> [FieldType m]
rowTypeFields RowType m
rt)
forall {a} {b} {c} {b} {c}.
Elimination (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldElimination (forall m. Projection -> Elimination m
EliminationRecord forall a b. (a -> b) -> a -> b
$ Name -> FieldName -> Projection
Projection Name
name FieldName
fname)
(forall m. Type m -> Type m -> Type m
Types.function (forall m. RowType m -> Type m
TypeRecord RowType m
rt) forall a b. (a -> b) -> a -> b
$ forall m. FieldType m -> Type m
fieldTypeType FieldType m
sfield) []
EliminationUnion (CaseStatement Name
name [Field m]
cases) -> do
RowType m
rt <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. Show m => Bool -> Name -> GraphFlow m (RowType m)
requireUnionType Bool
True Name
name
let sfields :: [FieldType m]
sfields = forall m. RowType m -> [FieldType m]
rowTypeFields RowType m
rt
[Field (m, Type m, [Constraint m])]
icases <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall m.
(Ord m, Show m) =>
Field m
-> Flow (InferenceContext m) (Field (m, Type m, [Constraint m]))
inferFieldType [Field m]
cases
let innerConstraints :: [Constraint m]
innerConstraints = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m. Field m -> Term m
fieldTerm forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Field (m, Type m, [Constraint m])]
icases)
let idoms :: [Type m]
idoms = forall m. Term (m, Type m, [Constraint m]) -> Type m
termType forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m. Field m -> Term m
fieldTerm forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Field (m, Type m, [Constraint m])]
icases
let sdoms :: [Type m]
sdoms = forall m. FieldType m -> Type m
fieldTypeType forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [FieldType m]
sfields
Type m
cod <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
let outerConstraints :: [Constraint m]
outerConstraints = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
L.zipWith (\Type m
t Type m
d -> (Type m
t, forall m. Type m -> Type m -> Type m
Types.function Type m
d Type m
cod)) [Type m]
idoms [Type m]
sdoms
forall {a} {b} {c} {b} {c}.
Elimination (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldElimination (forall m. CaseStatement m -> Elimination m
EliminationUnion (forall m. Name -> [Field m] -> CaseStatement m
CaseStatement Name
name [Field (m, Type m, [Constraint m])]
icases))
(forall m. Type m -> Type m -> Type m
Types.function (forall m. RowType m -> Type m
TypeUnion RowType m
rt) Type m
cod)
([Constraint m]
innerConstraints forall a. [a] -> [a] -> [a]
++ [Constraint m]
outerConstraints)
FunctionLambda (Lambda Variable
v Term m
body) -> do
Type m
tv <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
Term (m, Type m, [Constraint m])
i <- forall m a.
Variable
-> TypeScheme m
-> Flow (InferenceContext m) a
-> Flow (InferenceContext m) a
extendEnvironment Variable
v (forall m. [VariableType] -> Type m -> TypeScheme m
TypeScheme [] Type m
tv) forall a b. (a -> b) -> a -> b
$ forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
body
forall {a} {b} {c} {b} {c}.
Function (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldFunction (forall m. Lambda m -> Function m
FunctionLambda forall a b. (a -> b) -> a -> b
$ forall m. Variable -> Term m -> Lambda m
Lambda Variable
v Term (m, Type m, [Constraint m])
i) (forall m. Type m -> Type m -> Type m
Types.function Type m
tv (forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
i)) (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
i)
FunctionPrimitive Name
name -> do
FunctionType Type m
dom Type m
cod <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. Name -> GraphFlow m (FunctionType m)
typeOfPrimitiveFunction Name
name
forall {a} {b} {c} {b} {c}.
Function (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldFunction (forall m. Name -> Function m
FunctionPrimitive Name
name) (forall m. Type m -> Type m -> Type m
Types.function Type m
dom Type m
cod) []
TermLet (Let Variable
x Term m
e1 Term m
e2) -> do
(Context m
_, Int
_, TypingEnvironment m
env) <- forall s. Flow s s
getState
Term (m, Type m, [Constraint m])
i1 <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
e1
let t1 :: Type m
t1 = forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
i1
let c1 :: [Constraint m]
c1 = forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
i1
Subst m
sub <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. (Eq m, Show m) => [Constraint m] -> GraphFlow m (Subst m)
solveConstraints [Constraint m]
c1
let t1' :: Type m
t1' = forall m. (Ord m, Show m) => Type m -> Type m
reduceType forall a b. (a -> b) -> a -> b
$ forall m. Map VariableType (Type m) -> Type m -> Type m
substituteInType Subst m
sub Type m
t1
let sc :: TypeScheme m
sc = forall m. Show m => TypingEnvironment m -> Type m -> TypeScheme m
generalize (forall a b k. (a -> b) -> Map k a -> Map k b
M.map (forall m. Map VariableType (Type m) -> TypeScheme m -> TypeScheme m
substituteInScheme Subst m
sub) TypingEnvironment m
env) Type m
t1'
Term (m, Type m, [Constraint m])
i2 <- forall m a.
Variable
-> TypeScheme m
-> Flow (InferenceContext m) a
-> Flow (InferenceContext m) a
extendEnvironment Variable
x TypeScheme m
sc forall a b. (a -> b) -> a -> b
$ forall m a.
(TypingEnvironment m -> TypingEnvironment m)
-> Flow (InferenceContext m) a -> Flow (InferenceContext m) a
withEnvironment (forall a b k. (a -> b) -> Map k a -> Map k b
M.map (forall m. Map VariableType (Type m) -> TypeScheme m -> TypeScheme m
substituteInScheme Subst m
sub)) forall a b. (a -> b) -> a -> b
$ forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
e2
let t2 :: Type m
t2 = forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
i2
let c2 :: [Constraint m]
c2 = forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
i2
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Let m -> Term m
TermLet forall a b. (a -> b) -> a -> b
$ forall m. Variable -> Term m -> Term m -> Let m
Let Variable
x Term (m, Type m, [Constraint m])
i1 Term (m, Type m, [Constraint m])
i2) Type m
t2 ([Constraint m]
c1 forall a. [a] -> [a] -> [a]
++ [Constraint m]
c2)
TermList [Term m]
els -> do
Type m
v <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
[Term (m, Type m, [Constraint m])]
iels <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer [Term m]
els
let co :: [Constraint m]
co = (\Term (m, Type m, [Constraint m])
e -> (Type m
v, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
e)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Term (m, Type m, [Constraint m])]
iels
let ci :: [Constraint m]
ci = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Term (m, Type m, [Constraint m])]
iels)
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. [Term m] -> Term m
TermList [Term (m, Type m, [Constraint m])]
iels) (forall m. Type m -> Type m
Types.list Type m
v) ([Constraint m]
co forall a. [a] -> [a] -> [a]
++ [Constraint m]
ci)
TermLiteral Literal
l -> forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Literal -> Term m
TermLiteral Literal
l) (forall m. LiteralType -> Type m
Types.literal forall a b. (a -> b) -> a -> b
$ Literal -> LiteralType
literalType Literal
l) []
TermMap Map (Term m) (Term m)
m -> do
Type m
kv <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
Type m
vv <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
[(Term (m, Type m, [Constraint m]),
Term (m, Type m, [Constraint m]))]
pairs <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall {m}.
(Ord m, Show m) =>
(Term m, Term m)
-> Flow
(InferenceContext m)
(Term (m, Type m, [Constraint m]),
Term (m, Type m, [Constraint m]))
toPair forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [(k, a)]
M.toList Map (Term m) (Term m)
m
let co :: [Constraint m]
co = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat ((\(Term (m, Type m, [Constraint m])
k, Term (m, Type m, [Constraint m])
v) -> [(Type m
kv, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
k), (Type m
vv, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
v)]) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Term (m, Type m, [Constraint m]),
Term (m, Type m, [Constraint m]))]
pairs)
let ci :: [Constraint m]
ci = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat ((\(Term (m, Type m, [Constraint m])
k, Term (m, Type m, [Constraint m])
v) -> forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
k forall a. [a] -> [a] -> [a]
++ forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
v) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Term (m, Type m, [Constraint m]),
Term (m, Type m, [Constraint m]))]
pairs)
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Map (Term m) (Term m) -> Term m
TermMap forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(Term (m, Type m, [Constraint m]),
Term (m, Type m, [Constraint m]))]
pairs) (forall m. Type m -> Type m -> Type m
Types.map Type m
kv Type m
vv) ([Constraint m]
co forall a. [a] -> [a] -> [a]
++ [Constraint m]
ci)
where
toPair :: (Term m, Term m)
-> Flow
(InferenceContext m)
(Term (m, Type m, [Constraint m]),
Term (m, Type m, [Constraint m]))
toPair (Term m
k, Term m
v) = do
Term (m, Type m, [Constraint m])
ik <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
k
Term (m, Type m, [Constraint m])
iv <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
v
forall (m :: * -> *) a. Monad m => a -> m a
return (Term (m, Type m, [Constraint m])
ik, Term (m, Type m, [Constraint m])
iv)
TermNominal (Named Name
name Term m
term1) -> do
Type m
typ <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. Show m => String -> Name -> GraphFlow m (Type m)
namedType String
"nominal" Name
name
Term (m, Type m, [Constraint m])
i <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
term1
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Named m -> Term m
TermNominal forall a b. (a -> b) -> a -> b
$ forall m. Name -> Term m -> Named m
Named Name
name Term (m, Type m, [Constraint m])
i) (forall m. Name -> Type m
Types.nominal Name
name) (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
i forall a. [a] -> [a] -> [a]
++ [(Type m
typ, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
i)])
TermOptional Maybe (Term m)
m -> do
Type m
v <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
case Maybe (Term m)
m of
Maybe (Term m)
Nothing -> forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Maybe (Term m) -> Term m
TermOptional forall a. Maybe a
Nothing) (forall m. Type m -> Type m
Types.optional Type m
v) []
Just Term m
e -> do
Term (m, Type m, [Constraint m])
i <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
e
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Maybe (Term m) -> Term m
TermOptional forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Term (m, Type m, [Constraint m])
i) (forall m. Type m -> Type m
Types.optional Type m
v) ((Type m
v, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
i)forall a. a -> [a] -> [a]
:(forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
i))
TermProduct [Term m]
tuple -> do
[Term (m, Type m, [Constraint m])]
is <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer [Term m]
tuple
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. [Term m] -> Term m
TermProduct [Term (m, Type m, [Constraint m])]
is) (forall m. [Type m] -> Type m
TypeProduct forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall m. Term (m, Type m, [Constraint m]) -> Type m
termType [Term (m, Type m, [Constraint m])]
is) (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints [Term (m, Type m, [Constraint m])]
is)
TermRecord (Record Name
n [Field m]
fields) -> do
RowType m
rt <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. Show m => Bool -> Name -> GraphFlow m (RowType m)
requireRecordType Bool
True Name
n
let sfields :: [FieldType m]
sfields = forall m. RowType m -> [FieldType m]
rowTypeFields RowType m
rt
([Field (m, Type m, [Constraint m])]
fields0, [FieldType m]
ftypes0, [Constraint m]
c1) <- forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
CM.foldM forall {m}.
(Ord m, Show m) =>
([Field (m, Type m, [Constraint m])], [FieldType m],
[Constraint m])
-> (Field m, FieldType m)
-> Flow
(InferenceContext m)
([Field (m, Type m, [Constraint m])], [FieldType m],
[Constraint m])
forField ([], [], []) forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
L.zip [Field m]
fields [FieldType m]
sfields
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Record m -> Term m
TermRecord forall a b. (a -> b) -> a -> b
$ forall m. Name -> [Field m] -> Record m
Record Name
n forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
L.reverse [Field (m, Type m, [Constraint m])]
fields0) (forall m. RowType m -> Type m
TypeRecord forall a b. (a -> b) -> a -> b
$ forall m. Name -> Maybe Name -> [FieldType m] -> RowType m
RowType Name
n (forall m. RowType m -> Maybe Name
rowTypeExtends RowType m
rt) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
L.reverse [FieldType m]
ftypes0) [Constraint m]
c1
where
forField :: ([Field (m, Type m, [Constraint m])], [FieldType m],
[Constraint m])
-> (Field m, FieldType m)
-> Flow
(InferenceContext m)
([Field (m, Type m, [Constraint m])], [FieldType m],
[Constraint m])
forField ([Field (m, Type m, [Constraint m])]
typed, [FieldType m]
ftypes, [Constraint m]
c) (Field m
field, FieldType m
sfield) = do
Field (m, Type m, [Constraint m])
i <- forall m.
(Ord m, Show m) =>
Field m
-> Flow (InferenceContext m) (Field (m, Type m, [Constraint m]))
inferFieldType Field m
field
let ft :: Type m
ft = forall m. Term (m, Type m, [Constraint m]) -> Type m
termType forall a b. (a -> b) -> a -> b
$ forall m. Field m -> Term m
fieldTerm Field (m, Type m, [Constraint m])
i
let cinternal :: [Constraint m]
cinternal = forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints forall a b. (a -> b) -> a -> b
$ forall m. Field m -> Term m
fieldTerm Field (m, Type m, [Constraint m])
i
let cnominal :: Constraint m
cnominal = (Type m
ft, forall m. FieldType m -> Type m
fieldTypeType FieldType m
sfield)
forall (m :: * -> *) a. Monad m => a -> m a
return (Field (m, Type m, [Constraint m])
iforall a. a -> [a] -> [a]
:[Field (m, Type m, [Constraint m])]
typed, (forall m. FieldName -> Type m -> FieldType m
FieldType (forall m. Field m -> FieldName
fieldName Field m
field) Type m
ft)forall a. a -> [a] -> [a]
:[FieldType m]
ftypes, Constraint m
cnominalforall a. a -> [a] -> [a]
:([Constraint m]
cinternal forall a. [a] -> [a] -> [a]
++ [Constraint m]
c))
TermSet Set (Term m)
els -> do
Type m
v <- forall m. Flow (InferenceContext m) (Type m)
freshVariableType
[Term (m, Type m, [Constraint m])]
iels <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
CM.mapM forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer forall a b. (a -> b) -> a -> b
$ forall a. Set a -> [a]
S.toList Set (Term m)
els
let co :: [Constraint m]
co = (\Term (m, Type m, [Constraint m])
e -> (Type m
v, forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
e)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Term (m, Type m, [Constraint m])]
iels
let ci :: [Constraint m]
ci = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Term (m, Type m, [Constraint m])]
iels)
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Set (Term m) -> Term m
TermSet forall a b. (a -> b) -> a -> b
$ forall a. Ord a => [a] -> Set a
S.fromList [Term (m, Type m, [Constraint m])]
iels) (forall m. Type m -> Type m
Types.set Type m
v) ([Constraint m]
co forall a. [a] -> [a] -> [a]
++ [Constraint m]
ci)
TermSum (Sum Int
i Int
s Term m
trm) -> do
Term (m, Type m, [Constraint m])
it <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
trm
[Type m]
types <- forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
CM.sequence (forall {m}.
Term (m, Type m, [Constraint m])
-> Int -> Flow (InferenceContext m) (Type m)
varOrTerm Term (m, Type m, [Constraint m])
it forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
0..(Int
sforall a. Num a => a -> a -> a
-Int
1)])
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Sum m -> Term m
TermSum forall a b. (a -> b) -> a -> b
$ forall m. Int -> Int -> Term m -> Sum m
Sum Int
i Int
s Term (m, Type m, [Constraint m])
it) (forall m. [Type m] -> Type m
TypeSum [Type m]
types) (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
it)
where
varOrTerm :: Term (m, Type m, [Constraint m])
-> Int -> Flow (InferenceContext m) (Type m)
varOrTerm Term (m, Type m, [Constraint m])
it Int
j = if Int
i forall a. Eq a => a -> a -> Bool
== Int
j
then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
it
else forall m. Flow (InferenceContext m) (Type m)
freshVariableType
TermUnion (Union Name
n Field m
field) -> do
RowType m
rt <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m. Show m => Bool -> Name -> GraphFlow m (RowType m)
requireUnionType Bool
True Name
n
FieldType m
sfield <- forall m.
Show m =>
FieldName
-> [FieldType m] -> Flow (InferenceContext m) (FieldType m)
findMatchingField (forall m. Field m -> FieldName
fieldName Field m
field) (forall m. RowType m -> [FieldType m]
rowTypeFields RowType m
rt)
Field (m, Type m, [Constraint m])
ifield <- forall m.
(Ord m, Show m) =>
Field m
-> Flow (InferenceContext m) (Field (m, Type m, [Constraint m]))
inferFieldType Field m
field
let cinternal :: [Constraint m]
cinternal = forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints forall a b. (a -> b) -> a -> b
$ forall m. Field m -> Term m
fieldTerm Field (m, Type m, [Constraint m])
ifield
let cnominal :: Constraint m
cnominal = (forall m. Term (m, Type m, [Constraint m]) -> Type m
termType forall a b. (a -> b) -> a -> b
$ forall m. Field m -> Term m
fieldTerm Field (m, Type m, [Constraint m])
ifield, forall m. FieldType m -> Type m
fieldTypeType FieldType m
sfield)
let constraints :: [Constraint m]
constraints = Constraint m
cnominalforall a. a -> [a] -> [a]
:[Constraint m]
cinternal
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Union m -> Term m
TermUnion forall a b. (a -> b) -> a -> b
$ forall m. Name -> Field m -> Union m
Union Name
n Field (m, Type m, [Constraint m])
ifield) (forall m. RowType m -> Type m
TypeUnion RowType m
rt) [Constraint m]
constraints
TermVariable Variable
x -> do
Type m
t <- forall m. Show m => Variable -> Flow (InferenceContext m) (Type m)
lookupTypeInEnvironment Variable
x
forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Variable -> Term m
TermVariable Variable
x) Type m
t []
where
yieldFunction :: Function (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldFunction Function (a, b, c)
fun = forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Function m -> Term m
TermFunction Function (a, b, c)
fun)
yieldElimination :: Elimination (a, b, c)
-> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yieldElimination Elimination (a, b, c)
e = forall {a} {b} {c} {b} {c}.
Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield (forall m. Function m -> Term m
TermFunction forall a b. (a -> b) -> a -> b
$ forall m. Elimination m -> Function m
FunctionElimination Elimination (a, b, c)
e)
yield :: Term (a, b, c) -> b -> c -> Flow (Context a, b, c) (Term (a, b, c))
yield Term (a, b, c)
term b
typ c
constraints = do
(Context a
cx, b
_, c
_) <- forall s. Flow s s
getState
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall m. Annotated (Term m) m -> Term m
TermAnnotated forall a b. (a -> b) -> a -> b
$ forall a m. a -> m -> Annotated a m
Annotated Term (a, b, c)
term (forall m. AnnotationClass m -> m
annotationClassDefault forall a b. (a -> b) -> a -> b
$ forall m. Context m -> AnnotationClass m
contextAnnotations Context a
cx, b
typ, c
constraints)
inferFieldType :: (Ord m, Show m) => Field m -> Flow (InferenceContext m) (Field (m, Type m, [Constraint m]))
inferFieldType :: forall m.
(Ord m, Show m) =>
Field m
-> Flow (InferenceContext m) (Field (m, Type m, [Constraint m]))
inferFieldType (Field FieldName
fname Term m
term) = forall m. FieldName -> Term m -> Field m
Field FieldName
fname forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
term
inferType :: (Ord m, Show m) => Term m -> GraphFlow m (Term (m, Type m, [Constraint m]), TypeScheme m)
inferType :: forall m.
(Ord m, Show m) =>
Term m
-> GraphFlow m (Term (m, Type m, [Constraint m]), TypeScheme m)
inferType Term m
term = do
forall s a. String -> Flow s a -> Flow s a
withTrace (String
"infer type") forall a b. (a -> b) -> a -> b
$ do
Context m
cx <- forall s. Flow s s
getState
forall s1 a s2. s1 -> Flow s1 a -> Flow s2 a
withState (forall m. Context m -> InferenceContext m
startContext Context m
cx) forall a b. (a -> b) -> a -> b
$ do
Term (m, Type m, [Constraint m])
term1 <- forall m.
(Ord m, Show m) =>
Term m
-> Flow (InferenceContext m) (Term (m, Type m, [Constraint m]))
infer Term m
term
forall s a. String -> Flow s a -> Flow s a
withTrace (String
"original term (without annotations): " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall m. Ord m => Term m -> Term m
removeTermAnnotations Term m
term) forall a. [a] -> [a] -> [a]
++ String
" ### inferred term: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Term (m, Type m, [Constraint m])
term1) forall a b. (a -> b) -> a -> b
$ do
Subst m
subst <- forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext forall a b. (a -> b) -> a -> b
$ forall m a. GraphFlow m a -> GraphFlow m a
withSchemaContext forall a b. (a -> b) -> a -> b
$ forall m. (Eq m, Show m) => [Constraint m] -> GraphFlow m (Subst m)
solveConstraints (forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints Term (m, Type m, [Constraint m])
term1)
let term2 :: Term (m, Type m, [Constraint m])
term2 = forall m.
Ord m =>
(Type m -> Type m)
-> Term (m, Type m, [Constraint m])
-> Term (m, Type m, [Constraint m])
rewriteDataType (forall m. Map VariableType (Type m) -> Type m -> Type m
substituteInType Subst m
subst) Term (m, Type m, [Constraint m])
term1
forall (m :: * -> *) a. Monad m => a -> m a
return (Term (m, Type m, [Constraint m])
term2, Type m -> TypeScheme m
closeOver forall a b. (a -> b) -> a -> b
$ forall m. Term (m, Type m, [Constraint m]) -> Type m
termType Term (m, Type m, [Constraint m])
term2)
where
closeOver :: Type m -> TypeScheme m
closeOver = forall m. Show m => TypeScheme m -> TypeScheme m
normalizeScheme forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m. Show m => TypingEnvironment m -> Type m -> TypeScheme m
generalize forall k a. Map k a
M.empty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall m. (Ord m, Show m) => Type m -> Type m
reduceType
instantiate :: TypeScheme m -> Flow (InferenceContext m) (Type m)
instantiate :: forall m. TypeScheme m -> Flow (InferenceContext m) (Type m)
instantiate (TypeScheme [VariableType]
vars Type m
t) = do
[Type m]
vars1 <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a b. a -> b -> a
const forall m. Flow (InferenceContext m) (Type m)
freshVariableType) [VariableType]
vars
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall m. Map VariableType (Type m) -> Type m -> Type m
substituteInType (forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [VariableType]
vars [Type m]
vars1) Type m
t
lookupTypeInEnvironment :: Show m => Variable -> Flow (InferenceContext m) (Type m)
lookupTypeInEnvironment :: forall m. Show m => Variable -> Flow (InferenceContext m) (Type m)
lookupTypeInEnvironment Variable
v = do
(Context m
_, Int
_, TypingEnvironment m
env) <- forall s. Flow s s
getState
case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Variable
v TypingEnvironment m
env of
Maybe (TypeScheme m)
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"unbound variable: " forall a. [a] -> [a] -> [a]
++ Variable -> String
unVariable Variable
v
Just TypeScheme m
s -> forall m. TypeScheme m -> Flow (InferenceContext m) (Type m)
instantiate TypeScheme m
s
namedType :: Show m => String -> Name -> GraphFlow m (Type m)
namedType :: forall m. Show m => String -> Name -> GraphFlow m (Type m)
namedType String
debug Name
name = do
forall s a. String -> Flow s a -> Flow s a
withTrace (String
debug forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ Name -> String
unName Name
name) forall a b. (a -> b) -> a -> b
$ do
forall m a. GraphFlow m a -> GraphFlow m a
withSchemaContext forall a b. (a -> b) -> a -> b
$ do
Element m
el <- forall m. Name -> GraphFlow m (Element m)
requireElement Name
name
forall m. Show m => Term m -> GraphFlow m (Type m)
decodeStructuralType forall a b. (a -> b) -> a -> b
$ forall m. Element m -> Term m
elementData Element m
el
reduceType :: (Ord m, Show m) => Type m -> Type m
reduceType :: forall m. (Ord m, Show m) => Type m -> Type m
reduceType Type m
t = Type m
t
rewriteDataType :: Ord m => (Type m -> Type m) -> Term (m, Type m, [Constraint m]) -> Term (m, Type m, [Constraint m])
rewriteDataType :: forall m.
Ord m =>
(Type m -> Type m)
-> Term (m, Type m, [Constraint m])
-> Term (m, Type m, [Constraint m])
rewriteDataType Type m -> Type m
f = forall b a. Ord b => (a -> b) -> Term a -> Term b
rewriteTermMeta forall {a} {c}. (a, Type m, c) -> (a, Type m, c)
rewrite
where
rewrite :: (a, Type m, c) -> (a, Type m, c)
rewrite (a
x, Type m
typ, c
c) = (a
x, Type m -> Type m
f Type m
typ, c
c)
startContext :: Context m -> InferenceContext m
startContext :: forall m. Context m -> InferenceContext m
startContext Context m
cx = (Context m
cx, Int
0, forall k a. Map k a
M.empty)
termConstraints :: Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints :: forall m. Term (m, Type m, [Constraint m]) -> [Constraint m]
termConstraints (TermAnnotated (Annotated Term (m, Type m, [Constraint m])
_ (m
_, Type m
_, [Constraint m]
constraints))) = [Constraint m]
constraints
termType :: Term (m, Type m, [Constraint m]) -> Type m
termType :: forall m. Term (m, Type m, [Constraint m]) -> Type m
termType (TermAnnotated (Annotated Term (m, Type m, [Constraint m])
_ (m
_, Type m
typ, [Constraint m]
_))) = Type m
typ
typeOfElement :: Show m => Name -> GraphFlow m (Type m)
typeOfElement :: forall m. Show m => Name -> GraphFlow m (Type m)
typeOfElement Name
name = forall s a. String -> Flow s a -> Flow s a
withTrace String
"type of element" forall a b. (a -> b) -> a -> b
$ do
Element m
el <- forall m. Name -> GraphFlow m (Element m)
requireElement Name
name
forall m. Show m => Term m -> GraphFlow m (Type m)
decodeStructuralType forall a b. (a -> b) -> a -> b
$ forall m. Element m -> Term m
elementSchema Element m
el
typeOfPrimitiveFunction :: Name -> GraphFlow m (FunctionType m)
typeOfPrimitiveFunction :: forall m. Name -> GraphFlow m (FunctionType m)
typeOfPrimitiveFunction Name
name = forall m. PrimitiveFunction m -> FunctionType m
primitiveFunctionType forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m. Name -> GraphFlow m (PrimitiveFunction m)
requirePrimitiveFunction Name
name
withEnvironment :: (TypingEnvironment m -> TypingEnvironment m) -> Flow (InferenceContext m) a -> Flow (InferenceContext m) a
withEnvironment :: forall m a.
(TypingEnvironment m -> TypingEnvironment m)
-> Flow (InferenceContext m) a -> Flow (InferenceContext m) a
withEnvironment TypingEnvironment m -> TypingEnvironment m
m Flow (InferenceContext m) a
f = do
(Context m
cx, Int
i, TypingEnvironment m
e) <- forall s. Flow s s
getState
forall s1 a s2. s1 -> Flow s1 a -> Flow s2 a
withState (Context m
cx, Int
i, TypingEnvironment m -> TypingEnvironment m
m TypingEnvironment m
e) Flow (InferenceContext m) a
f
withGraphContext :: GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext :: forall m a. GraphFlow m a -> Flow (InferenceContext m) a
withGraphContext GraphFlow m a
f = do
(Context m
cx, Int
_, TypingEnvironment m
_) <- forall s. Flow s s
getState
forall s1 a s2. s1 -> Flow s1 a -> Flow s2 a
withState Context m
cx GraphFlow m a
f