diff --git a/primer/src/Primer/Eval/NormalOrder.hs b/primer/src/Primer/Eval/NormalOrder.hs index 2666b9765..b3e4583fa 100644 --- a/primer/src/Primer/Eval/NormalOrder.hs +++ b/primer/src/Primer/Eval/NormalOrder.hs @@ -44,6 +44,8 @@ import Primer.Core ( App, Case, Hole, + LAM, + Lam, Let, LetType, Letrec @@ -164,7 +166,7 @@ foldMapExpr extract topDir = flip evalAccumT mempty . go . (topDir,) . focus _ -> msum $ (goType =<< focusType' ez) - : map (go <=< hoistAccum) (exprChildren dez) + : map (go <=< hoistAccum) (exprChildrenClosed dez) goType :: TypeZ -> AccumT Cxt f a goType tz = readerToAccumT (ReaderT $ extract.ty tz) @@ -313,6 +315,17 @@ exprChildren (d, ez) = addBinds ez bs pure (d', c) +-- Extract the children of the current focus, except those under an "unknown" binder, +-- i.e. we extract the body of a let but not the body of a lambda, or the RHS of case branches. +-- This is used to restrict our evaluation to "closed evaluation". +-- NB: for consistency we skip all case branches, not just those that bind a variable. +exprChildrenClosed :: (Dir, ExprZ) -> [Accum Cxt (Dir, ExprZ)] +exprChildrenClosed (d, ez) = case target ez of + Lam{} -> [] + LAM{} -> [] + Case{} -> take 1 $ exprChildren (d, ez) -- just the scrutinee + _ -> exprChildren (d, ez) + typeChildren :: TypeZ -> [Accum Cxt TypeZ] typeChildren tz = children' tz <&> \c -> do