mirror of
https://github.com/unisonweb/unison.git
synced 2024-11-14 07:51:12 +03:00
annotateLetRecBindings
This commit is contained in:
parent
3e11768fcf
commit
84a69597f8
@ -74,6 +74,7 @@ data CompilerBug v loc
|
|||||||
= UnknownDecl Unknown Reference (Map Reference (DataDeclaration' v loc))
|
= UnknownDecl Unknown Reference (Map Reference (DataDeclaration' v loc))
|
||||||
| UnknownConstructor Unknown Reference Int (DataDeclaration' v loc)
|
| UnknownConstructor Unknown Reference Int (DataDeclaration' v loc)
|
||||||
| RetractFailure (Element v loc) (Context v loc)
|
| RetractFailure (Element v loc) (Context v loc)
|
||||||
|
| EmptyLetRec (Term v loc) -- the body of the empty let rec
|
||||||
|
|
||||||
data Note v loc
|
data Note v loc
|
||||||
= WithinSynthesize (Term v loc) (Note v loc)
|
= WithinSynthesize (Term v loc) (Note v loc)
|
||||||
@ -412,35 +413,36 @@ synthesize = error "synthesize todo"
|
|||||||
annotateLetRecBindings
|
annotateLetRecBindings
|
||||||
:: Var v => ((v -> M v loc v) -> M v loc ([(v, Term v loc)], Term v loc))
|
:: Var v => ((v -> M v loc v) -> M v loc ([(v, Term v loc)], Term v loc))
|
||||||
-> M v loc (Element v loc, Term v loc)
|
-> M v loc (Element v loc, Term v loc)
|
||||||
annotateLetRecBindings letrec =
|
annotateLetRecBindings letrec = do
|
||||||
error "todo"
|
(bindings, body) <- letrec freshenVar
|
||||||
--do
|
let vs = map fst bindings
|
||||||
--(bindings, body) <- letrec freshenVar
|
-- generate a fresh existential variable `e1, e2 ...` for each binding
|
||||||
--let vs = map fst bindings
|
es <- traverse freshenVar vs
|
||||||
---- generate a fresh existential variable `e1, e2 ...` for each binding
|
ctx <- getContext
|
||||||
--es <- traverse freshenVar vs
|
e1 <- case vs of
|
||||||
--ctx <- getContext
|
h : _t -> pure h
|
||||||
--e1 <- if null vs then fail "impossible" else pure $ head es
|
_ -> compilerCrash (EmptyLetRec body)
|
||||||
---- Introduce these existentials into the context and
|
-- Introduce these existentials into the context and
|
||||||
---- annotate each term variable w/ corresponding existential
|
-- annotate each term variable w/ corresponding existential
|
||||||
---- [marker e1, 'e1, 'e2, ... v1 : 'e1, v2 : 'e2 ...]
|
-- [marker e1, 'e1, 'e2, ... v1 : 'e1, v2 : 'e2 ...]
|
||||||
--let f e (_,binding) = case binding of
|
let f e (_,binding) = case binding of
|
||||||
-- -- TODO: Think about whether `apply` here is always correct
|
-- TODO: Think about whether `apply` here is always correct
|
||||||
-- -- Used to have a guard that would only do this if t had no free vars
|
-- Used to have a guard that would only do this if t had no free vars
|
||||||
-- Term.Ann' _ t -> apply ctx t
|
Term.Ann' _ t -> apply ctx t
|
||||||
-- _ -> Type.existential' (loc binding) e
|
_ -> Type.existential' (loc binding) e
|
||||||
--let bindingTypes = zipWith f es bindings
|
let bindingTypes = zipWith f es bindings
|
||||||
--appendContext $ context (Marker e1 : map Existential es ++ zipWith Ann vs bindingTypes)
|
appendContext $ context (Marker e1 : map Existential es ++ zipWith Ann vs bindingTypes)
|
||||||
---- check each `bi` against `ei`; sequencing resulting contexts
|
-- check each `bi` against `ei`; sequencing resulting contexts
|
||||||
--Foldable.for_ (zip bindings bindingTypes) $ \((_,b), t) -> check b t
|
Foldable.for_ (zip bindings bindingTypes) $ \((_,b), t) -> check b t
|
||||||
---- compute generalized types `gt1, gt2 ...` for each binding `b1, b2...`;
|
-- compute generalized types `gt1, gt2 ...` for each binding `b1, b2...`;
|
||||||
---- add annotations `v1 : gt1, v2 : gt2 ...` to the context
|
-- add annotations `v1 : gt1, v2 : gt2 ...` to the context
|
||||||
--(ctx1, ctx2) <- breakAt (Marker e1) <$> getContext
|
(ctx1, ctx2) <- breakAt (Marker e1) <$> getContext
|
||||||
--let gen e = generalizeExistentials ctx2 (Type.existential e)
|
-- The location of the existential is just the location of the binding
|
||||||
--let annotations = zipWith Ann vs (map gen es)
|
let gen (e,(_,binding)) = generalizeExistentials ctx2 (Type.existential' (loc binding) e)
|
||||||
--marker <- Marker <$> freshenVar (ABT.v' "let-rec-marker")
|
let annotations = zipWith Ann vs (map gen (es `zip` bindings))
|
||||||
--setContext (ctx1 `mappend` context (marker : annotations))
|
marker <- Marker <$> freshenVar (ABT.v' "let-rec-marker")
|
||||||
--pure $ (marker, body)
|
setContext (ctx1 `mappend` context (marker : annotations))
|
||||||
|
pure $ (marker, body)
|
||||||
|
|
||||||
-- | Apply the context to the input type, then convert any unsolved existentials
|
-- | Apply the context to the input type, then convert any unsolved existentials
|
||||||
-- to universals.
|
-- to universals.
|
||||||
@ -450,6 +452,9 @@ generalizeExistentials ctx t =
|
|||||||
where
|
where
|
||||||
gen e t =
|
gen e t =
|
||||||
if TypeVar.Existential e `ABT.isFreeIn` t
|
if TypeVar.Existential e `ABT.isFreeIn` t
|
||||||
|
-- location of the forall is just the location of the input type
|
||||||
|
-- and the location of each quantified variable is just inherited from
|
||||||
|
-- its source location
|
||||||
then Type.forall (loc t) (TypeVar.Universal e) (ABT.substInheritAnnotation (TypeVar.Existential e) (Type.universal e) t)
|
then Type.forall (loc t) (TypeVar.Universal e) (ABT.substInheritAnnotation (TypeVar.Existential e) (Type.universal e) t)
|
||||||
else t -- don't bother introducing a forall if type variable is unused
|
else t -- don't bother introducing a forall if type variable is unused
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user