annotateLetRecBindings

This commit is contained in:
Paul Chiusano 2018-07-16 12:24:23 -04:00
parent 3e11768fcf
commit 84a69597f8

View File

@ -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