@@ -1883,28 +1883,30 @@ resetContextAfter x a = do
18831883 setContext ctx
18841884 pure a
18851885
1886+ type LetRecInfo v loc =
1887+ (v -> M v loc v ) -> M v loc ([((loc , v ), Term v loc )], Term v loc )
1888+
18861889-- | Synthesize and generalize the type of each binding in a let rec.
18871890-- Updates the context so that all bindings are annotated with
18881891-- their type. Also returns the freshened version of `body`.
18891892-- See usage in `synthesize` and `check` for `LetRec'` case.
18901893annotateLetRecBindings ::
18911894 (Var v , Ord loc , Semigroup loc ) =>
1892- Term. IsTop ->
1893- ((v -> M v loc v ) -> M v loc ([((loc , v ), Term v loc )], Term v loc )) ->
1894- M v loc (Term v loc )
1895+ Term. IsTop -> LetRecInfo v loc -> M v loc (Term v loc )
18951896annotateLetRecBindings isTop letrec =
18961897 -- If this is a top-level letrec, then emit a TopLevelComponent note,
18971898 -- which asks if the user-provided type annotations were needed.
18981899 if isTop
18991900 then do
19001901 -- First, typecheck (using annotateLetRecBindings') the bindings with any
19011902 -- user-provided annotations.
1902- (body, vts) <- annotateLetRecBindings' True
1903+ (body, vts) <- annotateLetRecBindings' letrec True
19031904 -- Then, try typechecking again, but ignoring any user-provided annotations.
19041905 -- This will infer whatever type. If it altogether fails to typecheck here
19051906 -- then, ...(1)
19061907 withoutAnnotations <-
1907- resetContextAfter Nothing $ Just <$> annotateLetRecBindings' False
1908+ resetContextAfter Nothing $
1909+ Just <$> annotateLetRecBindings' letrec False
19081910 -- convert from typechecker TypeVar back to regular `v` vars
19091911 let unTypeVar (v, t) = (v, generalizeAndUnTypeVar t)
19101912 case withoutAnnotations of
@@ -1918,58 +1920,147 @@ annotateLetRecBindings isTop letrec =
19181920 pure body
19191921 else do
19201922 -- If this isn't a top-level letrec, then we don't have to do anything special
1921- (body, _vts) <- annotateLetRecBindings' True
1923+ (body, _vts) <- annotateLetRecBindings' letrec True
19221924 pure body
1925+
1926+ -- A wrapper type for demuxed binding information in a let. Only used
1927+ -- locally.
1928+ data Bindings v loc
1929+ = Bindings
1930+ { bnds :: [Term v loc ], -- actual bindings
1931+ bndTyps :: [Type v loc ], -- types for the bindings
1932+ bndVars :: [v ], -- variables the bindings are bound to
1933+ bndVarLocs :: [loc ] -- locations of said variables
1934+ }
1935+
1936+ demuxBindings :: [(Term v loc , Type v loc , v , loc )] -> Bindings v loc
1937+ demuxBindings = uncurry4 Bindings . unzip4
1938+
1939+ -- Calculates the associations between variables and their bindings in
1940+ -- a `Bindings`, discarding some of the other information.
1941+ namedBindings :: Bindings v loc -> [(v , Term v loc )]
1942+ namedBindings bs = bndVars bs `zip` bnds bs
1943+
1944+ -- Helper function for checking recursive let bindings. This is the
1945+ -- part of the check that processes the type of the _bindings_, and
1946+ -- returns information that can be used to subsequently check the
1947+ -- body.
1948+ --
1949+ -- To achieve better results, this classifies the bindings into two
1950+ -- categories
1951+ --
1952+ -- 1. Bindings given with completely closed types, that need no
1953+ -- parts inferred.
1954+ -- 2. Bindings that need at least some part of the type inferred.
1955+ --
1956+ -- The first category can be checked _last_, under the presumption
1957+ -- that the given types are accurate, because the checking of the
1958+ -- second category has no effect on the types in the first category.
1959+ -- This allows us to _generalize_ the types in the second category
1960+ -- before checking the first category. This is necessary when you have
1961+ -- examples like:
1962+ --
1963+ -- f x = g x
1964+ -- g : a -> b
1965+ -- g x = f x
1966+ --
1967+ -- because otherwise the inferred type of `f` will seem too concrete
1968+ -- for the checking of `g` to succeed.
1969+ --
1970+ -- Note however that "closed" can be somewhat deceptive. The type of
1971+ -- `g` above is actually not closed, because it is shorthand for the
1972+ -- type `a ->{e} b`, where the `e` needs to be inferred. To avoid this
1973+ -- defeating the whole approach, it's advisable to be somewhat
1974+ -- conservative with making up these inference variables. For instance
1975+ --
1976+ -- f : a -> b -> c ->{E} d
1977+ -- f x y z = ...
1978+ --
1979+ -- can be immediately completed to `a ->{} b ->{} c ->{E} d` instead
1980+ -- of making up variables for the two positions that must be pure.
1981+ annotateLetRecBindings' ::
1982+ (Var v , Ord loc , Semigroup loc ) =>
1983+ LetRecInfo v loc ->
1984+ Bool ->
1985+ M v loc (Term v loc , [(v , Type v loc )])
1986+ annotateLetRecBindings' letrec useAnn = do
1987+ (binds, body) <- letrec freshenVar
1988+
1989+ ((allbnds, abnds, ubnds), ctx) <-
1990+ markThenRetract Var. inferOther $ do
1991+ binds <- traverse prepare binds
1992+ let (unanns, anns) = partitionEithers binds
1993+ ubnds = demuxBindings unanns
1994+ abnds = demuxBindings anns
1995+ allbnds = demuxBindings $ map (either id id ) binds
1996+
1997+ -- check un-annotated bindings against their types
1998+ appendContext (varAnns allbnds)
1999+
2000+ Foldable. for_ (vbts ubnds) \ (v, b, t) -> do
2001+ -- elements of a cycle need to be pure, otherwise order of
2002+ -- effects is unclear and chaos ensues.
2003+
2004+ -- ensure actions in blocks have type ()
2005+ when (Var. isAction v) . scope InActionRestriction $
2006+ subtype t (DDB. unitType (ABT. annotation b))
2007+ insideDef v $ checkScopedWith b t []
2008+
2009+ pure (allbnds, abnds, ubnds)
2010+
2011+ -- compute generalized types for bindings that needed inference
2012+ vars <- getVariances
2013+ let bindingArities = Term. arity <$> bnds ubnds
2014+ gen bty _arity =
2015+ generalizeExistentials ctx vars bty
2016+ gbndTyps = zipWith gen (bndTyps ubnds) bindingArities
2017+ genAnns =
2018+ zipWith3 Ann (bndVars ubnds) (bndVarLocs ubnds) gbndTyps
2019+
2020+ allAnns = genAnns ++ varAnns abnds
2021+
2022+ appendContext allAnns
2023+
2024+ -- check annotated bindings
2025+ _ <- markThenRetract Var. inferOther $ do
2026+ Foldable. for_ (vbts abnds) \ (v, b, t) -> do
2027+ when (Var. isAction v) . scope InActionRestriction $
2028+ subtype t (DDB. unitType (ABT. annotation b))
2029+ insideDef v $ checkScopedWith b t []
2030+
2031+ ensureGuardedCycle (namedBindings allbnds)
2032+
2033+ let vTypes =
2034+ zip (bndVars ubnds) gbndTyps
2035+ ++ zip (bndVars abnds) (bndTyps abnds)
2036+
2037+ pure (body, vTypes)
19232038 where
1924- annotateLetRecBindings' useUserAnnotations = do
1925- (bindings, body) <- letrec freshenVar
1926- let vs = map (snd . fst ) bindings
1927- ((bindings, bindingTypes, vlocs), ctx2) <- markThenRetract Var. inferOther $ do
1928- let f ((vloc, v), binding) = case binding of
1929- -- If user has provided an annotation, we use that
1930- Term. Ann' e t | useUserAnnotations -> do
1931- -- Arrows in `t` with no ability lists get an attached fresh
1932- -- existential to allow inference of required abilities
1933- t2 <- existentializeArrows =<< applyM t
1934- pure (Term. ann (loc binding) e t2, t2, vloc)
1935- -- If we're not using an annotation, we make one up. There's 2 cases:
1936-
1937- lam@ (Term. Lam' {}) ->
1938- -- If `e` is a lambda of arity K, we immediately refine the
1939- -- existential to `a1 ->{e1} a2 ... ->{eK} r`. This gives better
1940- -- inference of the lambda's ability variables in conjunction with
1941- -- handling of lambdas in `check` judgement.
1942- (lam,,vloc) <$> existentialFunctionTypeFor lam
1943- e -> do
1944- -- Anything else, just make up a fresh existential
1945- -- which will be refined during typechecking of the binding
1946- vt <- extendExistential v
1947- pure $ (e, existential' (loc binding) B. Blank vt, vloc)
1948- (bindings, bindingTypes, vlocs) <- unzip3 <$> traverse f bindings
1949- appendContext (zipWith3 Ann vs vlocs bindingTypes)
1950- -- check each `bi` against its type
1951- Foldable. for_ (zip3 vs bindings bindingTypes) $ \ (v, b, t) -> do
1952- -- note: elements of a cycle have to be pure, otherwise order of effects
1953- -- is unclear and chaos ensues
1954-
1955- -- ensure actions in blocks have type ()
1956- when (Var. isAction v) . scope InActionRestriction $
1957- subtype t (DDB. unitType (ABT. annotation b))
1958- insideDef v $ checkScopedWith b t []
1959- ensureGuardedCycle (vs `zip` bindings)
1960- pure (bindings, bindingTypes, vlocs)
1961- -- compute generalized types `gt1, gt2 ...` for each binding `b1, b2...`;
1962- -- add annotations `v1 : gt1, v2 : gt2 ...` to the context
1963- vars <- getVariances
1964- let bindingArities = Term. arity <$> bindings
1965- gen bindingType _arity =
1966- generalizeExistentials ctx2 vars bindingType
1967- bindingTypesGeneralized = zipWith gen bindingTypes bindingArities
1968- annotations = zipWith3 Ann vs vlocs bindingTypesGeneralized
1969-
1970- appendContext annotations
1971- let vTypes = vs `zip` bindingTypesGeneralized
1972- pure (body, vTypes)
2039+ closed = Set. null . ABT. freeVars
2040+ indicate t = if closed t then Right else Left
2041+
2042+ varAnns bs = zipWith3 Ann (bndVars bs) (bndVarLocs bs) (bndTyps bs)
2043+
2044+ vbts bs = zip3 (bndVars bs) (bnds bs) (bndTyps bs)
2045+
2046+ prepare ((vloc, v), binding)
2047+ -- If a term has an annotation add any missing ability
2048+ -- annotations. We indicate whether the type is completely
2049+ -- closed, because such types can be separated out of the
2050+ -- binding cycle.
2051+ | useAnn,
2052+ Term. Ann' e t <- binding = do
2053+ t <- addAbilities (countLambdas e) =<< applyM t
2054+ pure $ indicate t (Term. ann (loc binding) e t, t, v, vloc)
2055+ -- If the term is a lambda, we immediately make a refined type
2056+ -- for better inference.
2057+ | Term. Lam' {} <- binding =
2058+ Left . (binding,,v,vloc)
2059+ <$> existentialFunctionTypeFor binding
2060+ -- otherwise just make up a fresh existential and proceed
2061+ | otherwise = do
2062+ vt <- extendExistential v
2063+ pure $ Left (binding, existential' (loc binding) B. Blank vt, v, vloc)
19732064
19742065ensureGuardedCycle :: (Var v ) => [(v , Term v loc )] -> M v loc ()
19752066ensureGuardedCycle bindings =
@@ -1984,16 +2075,24 @@ ensureGuardedCycle bindings =
19842075 then pure ()
19852076 else failWith $ UnguardedLetRecCycle (fst <$> notok) bindings
19862077
1987- existentialFunctionTypeFor :: (Ord loc , Var v ) => Term v loc -> M v loc (Type v loc )
1988- existentialFunctionTypeFor lam@ (Term. LamNamed' v body) = do
1989- v <- extendExistential v
2078+ -- Create a n existential type for a lambda term.
2079+ --
2080+ -- Note: for lambdas like `x y z -> ...` only the abilities after z
2081+ -- will ever be non-empty, so we can just make up empty ability lists
2082+ -- for repeated lambdas.
2083+ existentialFunctionTypeFor ::
2084+ (Ord loc , Var v ) => Term v loc -> M v loc (Type v loc )
2085+ existentialFunctionTypeFor lam@ (Term. LamsNamed' vs _) = do
2086+ let expl = existentialp (loc lam)
2087+ us <- traverse extendExistential vs
19902088 e <- extendExistential Var. inferAbility
1991- o <- existentialFunctionTypeFor body
1992- pure $
1993- Type. arrow
1994- (loc lam)
1995- (existentialp (loc lam) v)
1996- (Type. effect (loc lam) [existentialp (loc lam) e] o)
2089+ o <- extendExistential Var. inferOutput
2090+ let f u t =
2091+ Type. arrow
2092+ (loc lam)
2093+ (expl u)
2094+ (Type. effect (loc lam) [] t)
2095+ pure $ foldr f (Type. effect (loc lam) [expl e] (expl o)) us
19972096existentialFunctionTypeFor e = do
19982097 v <- extendExistential Var. inferOutput
19992098 pure $ existentialp (loc e) v
@@ -2004,6 +2103,38 @@ existentializeArrows t = do
20042103 t <- Type. existentializeArrows newVar t
20052104 pure t
20062105
2106+ -- Adds ability lists to arrows in a type that lack them. Unlike
2107+ -- `existentializeArrows`, this takes a count for a corresponding
2108+ -- repeated lambda, like
2109+ --
2110+ -- w x y z -> ...
2111+ --
2112+ -- since it is impossible for abilities to be used except after `z` in
2113+ -- such a case, this avoids making up variables for them. The `Int`
2114+ -- argument specifies how many repeated variables there are in the
2115+ -- corresponding term.
2116+ addAbilities :: (Var v ) => Int -> Type v loc -> M v loc (Type v loc )
2117+ addAbilities ct ty
2118+ | a <- ABT. annotation ty,
2119+ Type. ForallsNamed' vs ty <- ty =
2120+ Type. foralls a vs <$> addAbilities ct ty
2121+ -- Note: Arrow'' matches even with no abilities, providing []
2122+ | ct > 1 ,
2123+ Type. Arrow'' a es b <- ty = do
2124+ a <- existentializeArrows a
2125+ b <- addAbilities (ct - 1 ) b
2126+ pure $ Type. arrow ann a (Type. effect ann es b)
2127+ | otherwise = existentializeArrows ty
2128+ where
2129+ ann = ABT. annotation ty
2130+
2131+ -- Counts the number of iterated lambdas in a term; for use with the
2132+ -- above `addAbilities`
2133+ countLambdas :: Term v loc -> Int
2134+ countLambdas tm
2135+ | Term. LamsNamed' vs _ <- tm = length vs
2136+ | otherwise = 0
2137+
20072138ungeneralize :: (Var v , Ord loc ) => Type v loc -> M v loc (Type v loc )
20082139ungeneralize t = snd <$> ungeneralize' t
20092140
@@ -2213,7 +2344,7 @@ checkScoped e (Type.Forall' body) = do
22132344 want <- substAndDefaultWanted want pop
22142345 pure (generalizeP variableP pop ty, want)
22152346checkScoped e t = do
2216- t <- existentializeArrows t
2347+ t <- addAbilities (countLambdas e) t
22172348 (t,) <$> check e t
22182349
22192350checkScopedWith ::
0 commit comments