@@ -1455,177 +1455,80 @@ confuseGHCBuilder :: IRRep r => BuilderM r n (DistinctEvidence n)
14551455confuseGHCBuilder = getDistinct
14561456{-# INLINE confuseGHCBuilder #-}
14571457
1458- -- === Traversal helpers ===
1459-
1460- -- These traversals work with `TraversableTerm` but they make more assumptions
1461- -- about the monad you're in.
1462-
1463- type ForallTraversalDef m r = forall i o . TraversalDef (m i o ) r i o
1464- type ExprTraversalDef m r = forall i o . Expr r i -> m i o (Expr r o )
1465- type BlockTraversalDef m r = forall i o . Block r i -> m i o (Block r o )
1466-
1467- traverseExprs
1468- :: (IRRep r , TraversableTerm e r , EnvExtender2 m , SubstReader Name m )
1469- => e i -> ExprTraversalDef m r -> m i o (e o )
1470- traverseExprs e f = traverseTerm (exprTraversal f) e where
1471-
1472- exprTraversal
1473- :: (IRRep r , EnvExtender2 m , SubstReader Name m )
1474- => ExprTraversalDef m r -> ForallTraversalDef m r
1475- exprTraversal f = TraversalDef
1476- { handleName = renameM
1477- , handleType = traverseTypeRename (exprTraversal f)
1478- , handleAtom = traverseAtomRename (exprTraversal f)
1479- , handleLam = traverseLam (exprTraversal f) (traverseBlock (exprTraversal f) f)
1480- , handlePi = traversePi (exprTraversal f) }
1481-
1482- traverseBlock
1483- :: (IRRep r , FromName v , SubstReader v m , EnvExtender2 m )
1484- => ForallTraversalDef m r
1485- -> ExprTraversalDef m r
1486- -> Block r i -> m i o (Block r o )
1487- traverseBlock f fExpr (Block _ decls result) = do
1488- absToBlockInferringTypes =<< traverseDecls fExpr decls \ decls' -> do
1489- result' <- handleAtom f result
1490- return $ Abs decls' result'
1491-
1492- traverseAtomRename
1493- :: (IRRep r , SubstReader Name m , EnvExtender2 m )
1494- => ForallTraversalDef m r
1495- -> Atom r i -> m i o (Atom r o )
1496- traverseAtomRename f = \ case
1497- Var v -> Var <$> renameM v
1498- SimpInCore x -> SimpInCore <$> renameM x
1499- ProjectElt i x -> ProjectElt i <$> traverseAtomRename f x
1500- x -> traverseAtom f x
1501-
1502- traverseTypeRename
1503- :: (IRRep r , SubstReader Name m , EnvExtender2 m )
1504- => ForallTraversalDef m r
1505- -> Type r i -> m i o (Type r o )
1506- traverseTypeRename f = \ case
1507- TyVar v -> TyVar <$> renameM v
1508- ProjectEltTy i x -> ProjectEltTy i <$> traverseAtomRename f x
1509- x -> traverseType f x
1510-
1511- traverseLam
1512- :: (IRRep r , FromName v , SubstReader v m , EnvExtender2 m )
1513- => ForallTraversalDef m r
1514- -> BlockTraversalDef m r
1515- -> LamExpr r i -> m i o (LamExpr r o )
1516- traverseLam f fBlock (LamExpr bs body) =
1517- traverseBinders f bs \ bs' -> LamExpr bs' <$> fBlock body
1518-
1519- traversePi
1520- :: (IRRep r , FromName v , SubstReader v m , EnvExtender2 m )
1521- => ForallTraversalDef m r -> PiType r i -> m i o (PiType r o )
1522- traversePi f (PiType bs eff ty) = do
1523- traverseBinders f bs \ bs' -> do
1524- EffectAndType eff' ty' <- traverseTerm f $ EffectAndType eff ty
1525- return $ PiType bs' eff' ty'
1526-
1527- traverseBinders
1528- :: (IRRep r , FromName v , SubstReader v m , EnvExtender2 m )
1529- => ForallTraversalDef m r
1530- -> Nest (Binder r ) i i'
1531- -> (forall o' . DExt o o' => Nest (Binder r ) o o' -> m i' o' a )
1532- -> m i o a
1533- traverseBinders _ Empty cont = getDistinct >>= \ Distinct -> cont Empty
1534- traverseBinders f (Nest (b:> ty) bs) cont = do
1535- ty' <- handleType f ty
1536- withFreshBinder (getNameHint b) ty' \ b' -> do
1537- extendRenamer (b@> binderName b') do
1538- traverseBinders f bs \ bs' ->
1539- cont $ Nest b' bs'
1458+ -- === Non-emitting expression visitor ===
1459+
1460+ class Visitor m r i o => ExprVisitorNoEmits m r i o | m -> i , m -> o where
1461+ visitExprNoEmits :: Expr r i -> m (Expr r o )
1462+
1463+ type ExprVisitorNoEmits2 m r = forall i o . ExprVisitorNoEmits (m i o ) r i o
15401464
1541- traverseDecls
1542- :: (IRRep r , FromName v , SubstReader v m , EnvExtender2 m )
1543- => ExprTraversalDef m r
1544- -> Nest (Decl r ) i i'
1465+ visitLamNoEmits
1466+ :: (ExprVisitorNoEmits2 m r , IRRep r , AtomSubstReader v m , EnvExtender2 m )
1467+ => LamExpr r i -> m i o (LamExpr r o )
1468+ visitLamNoEmits (LamExpr bs body) =
1469+ visitBinders bs \ bs' -> LamExpr bs' <$> visitBlockNoEmits body
1470+
1471+ visitBlockNoEmits
1472+ :: (ExprVisitorNoEmits2 m r , IRRep r , AtomSubstReader v m , EnvExtender2 m )
1473+ => Block r i -> m i o (Block r o )
1474+ visitBlockNoEmits (Block _ decls result) =
1475+ absToBlockInferringTypes =<< visitDeclsNoEmits decls \ decls' -> do
1476+ Abs decls' <$> visitAtom result
1477+
1478+ visitDeclsNoEmits
1479+ :: (ExprVisitorNoEmits2 m r , IRRep r , AtomSubstReader v m , EnvExtender2 m )
1480+ => Nest (Decl r ) i i'
15451481 -> (forall o' . DExt o o' => Nest (Decl r ) o o' -> m i' o' a )
15461482 -> m i o a
1547- traverseDecls _ Empty cont = getDistinct >>= \ Distinct -> cont Empty
1548- traverseDecls f (Nest (Let b (DeclBinding ann _ expr)) decls) cont = do
1549- expr' <- f expr
1483+ visitDeclsNoEmits Empty cont = getDistinct >>= \ Distinct -> cont Empty
1484+ visitDeclsNoEmits (Nest (Let b (DeclBinding ann _ expr)) decls) cont = do
1485+ expr' <- visitExprNoEmits expr
15501486 ty <- getType expr'
15511487 withFreshBinder (getNameHint b) ty \ (b':> _) -> do
15521488 let decl' = Let b' $ DeclBinding ann ty expr'
15531489 extendRenamer (b@> binderName b') do
1554- traverseDecls f decls \ decls' ->
1490+ visitDeclsNoEmits decls \ decls' ->
15551491 cont $ Nest decl' decls'
15561492
1557- -- === traversal helpers that allow emissions ===
1558-
1559- type ExprEmitTraversalDef m r = forall i o . Emits o = > Expr r i -> m i o (Atom r o )
1560-
1561- liftAtomSubstBuilder :: (IRRep r , EnvReader m ) => AtomSubstBuilder r n n a -> m n a
1562- liftAtomSubstBuilder cont = liftBuilder $ runSubstReaderT idSubst cont
1563-
1564- type AtomSubstBuilder r = SubstReaderT AtomSubstVal (BuilderM r )
1565-
1566- exprEmitTraversal
1567- :: (IRRep r , ScopableBuilder2 r m , SubstReader AtomSubstVal m )
1568- => ExprEmitTraversalDef m r -> ForallTraversalDef m r
1569- exprEmitTraversal f = TraversalDef
1570- { handleName = substM
1571- , handleType = traverseTypeSubst (exprEmitTraversal f)
1572- , handleAtom = traverseAtomSubst (exprEmitTraversal f)
1573- , handleLam = traverseLamEmit (exprEmitTraversal f) f
1574- , handlePi = traversePi (exprEmitTraversal f) }
1575-
1576- traverseLamEmit
1577- :: (IRRep r , SubstReader AtomSubstVal m , ScopableBuilder2 r m )
1578- => ForallTraversalDef m r
1579- -> ExprEmitTraversalDef m r
1580- -> LamExpr r i -> m i o (LamExpr r o )
1581- traverseLamEmit f fExpr lam =
1582- traverseLam f (\ b -> buildBlock $ traverseBlockEmit f fExpr b) lam
1583-
1584- traverseBlockEmit
1585- :: (Emits o , IRRep r , SubstReader AtomSubstVal m , EnvExtender2 m )
1586- => ForallTraversalDef m r
1587- -> ExprEmitTraversalDef m r
1588- -> Block r i -> m i o (Atom r o )
1589- traverseBlockEmit f fExpr (Block _ decls result) = do
1590- traverseDeclsEmit fExpr decls do
1591- handleAtom f result
1592-
1593- traverseDeclsEmit
1594- :: (IRRep r , SubstReader AtomSubstVal m , EnvExtender2 m , Emits o )
1595- => ExprEmitTraversalDef m r
1596- -> Nest (Decl r ) i i'
1493+ -- === Emitting expression visitor ===
1494+
1495+ class Visitor m r i o => ExprVisitorEmits m r i o | m -> i , m -> o where
1496+ visitExprEmits :: Emits o => Expr r i -> m (Atom r o )
1497+
1498+ type ExprVisitorEmits2 m r = forall i o . ExprVisitorEmits (m i o ) r i o
1499+
1500+ liftAtomSubstBuilder :: forall tag r m n a . (IRRep r , EnvReader m ) => AtomSubstBuilder tag r n n a -> m n a
1501+ liftAtomSubstBuilder cont = liftBuilder $ runSubstReaderT idSubst $ runAtomSubstBuilder cont
1502+
1503+ -- The phantom type `v` is for defining `Visitor` instances. The pattern is to
1504+ -- define a new singleton type, like `data MyTag = MyTag`.
1505+ newtype AtomSubstBuilder v r i o a =
1506+ AtomSubstBuilder { runAtomSubstBuilder :: SubstReaderT AtomSubstVal (BuilderM r ) i o a }
1507+ deriving (MonadFail , Fallible , Functor , Applicative , Monad , ScopeReader ,
1508+ EnvReader , EnvExtender , Builder r, SubstReader AtomSubstVal ,
1509+ ScopableBuilder r)
1510+
1511+ visitLamEmits
1512+ :: (ExprVisitorEmits2 m r , IRRep r , SubstReader AtomSubstVal m , ScopableBuilder2 r m )
1513+ => LamExpr r i -> m i o (LamExpr r o )
1514+ visitLamEmits (LamExpr bs body) = visitBinders bs \ bs' -> LamExpr bs' <$>
1515+ buildBlock (visitBlockEmits body)
1516+
1517+ visitBlockEmits
1518+ :: (ExprVisitorEmits2 m r , SubstReader AtomSubstVal m , EnvExtender2 m , IRRep r , Emits o )
1519+ => Block r i -> m i o (Atom r o )
1520+ visitBlockEmits (Block _ decls result) = visitDeclsEmits decls $ visitAtom result
1521+
1522+ visitDeclsEmits
1523+ :: (ExprVisitorEmits2 m r , SubstReader AtomSubstVal m , EnvExtender2 m , IRRep r , Emits o )
1524+ => Nest (Decl r ) i i'
15971525 -> m i' o a
15981526 -> m i o a
1599- traverseDeclsEmit _ Empty cont = cont
1600- traverseDeclsEmit f (Nest (Let b (DeclBinding _ _ expr)) decls) cont = do
1601- x <- f expr
1527+ visitDeclsEmits Empty cont = cont
1528+ visitDeclsEmits (Nest (Let b (DeclBinding _ _ expr)) decls) cont = do
1529+ x <- visitExprEmits expr
16021530 extendSubst (b@> SubstVal x) do
1603- traverseDeclsEmit f decls cont
1604-
1605- traverseExprsEmit
1606- :: (IRRep r , ScopableBuilder2 r m , SubstReader AtomSubstVal m
1607- , TraversableTerm e r )
1608- => e i -> ExprEmitTraversalDef m r -> m i o (e o )
1609- traverseExprsEmit e f = traverseTerm (exprEmitTraversal f) e where
1610-
1611- traverseAtomSubst
1612- :: (IRRep r , SubstReader AtomSubstVal m , EnvExtender2 m )
1613- => ForallTraversalDef m r
1614- -> Atom r i -> m i o (Atom r o )
1615- traverseAtomSubst f = \ case
1616- Var v -> substM $ Var v
1617- SimpInCore x -> SimpInCore <$> substM x
1618- ProjectElt i x -> ProjectElt i <$> traverseAtomSubst f x
1619- x -> traverseAtom f x
1620-
1621- traverseTypeSubst
1622- :: (IRRep r , SubstReader AtomSubstVal m , EnvExtender2 m )
1623- => ForallTraversalDef m r
1624- -> Type r i -> m i o (Type r o )
1625- traverseTypeSubst f = \ case
1626- TyVar v -> substM $ TyVar v
1627- ProjectEltTy i x -> ProjectEltTy i <$> traverseAtomSubst f x
1628- x -> traverseType f x
1531+ visitDeclsEmits decls cont
16291532
16301533-- === Helpers for function evaluation over fixed-width types ===
16311534
0 commit comments