Skip to content

Commit 6ea43db

Browse files
committed
Query effects on the input expression in transposition instead of blindly substituting.
1 parent f24247d commit 6ea43db

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

src/lib/Transpose.hs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ type LinRegions = ListE AtomName
4848
type TransposeM a = SubstReaderT TransposeSubstVal
4949
(ReaderT1 LinRegions BuilderM) a
5050

51+
type TransposeM' a = SubstReaderT AtomSubstVal
52+
(ReaderT1 LinRegions BuilderM) a
53+
5154
-- TODO: it might make sense to replace substNonlin/isLin
5255
-- with a single `trySubtNonlin :: e i -> Maybe (e o)`.
5356
-- But for that we need a way to traverse names, like a monadic
@@ -60,6 +63,22 @@ substNonlin e = do
6063
RenameNonlin v' -> v'
6164
_ -> error "not a nonlinear expression") e
6265

66+
-- TODO: Can we generalize onNonLin to accept SubstReaderT Name instead of
67+
-- SubstReaderT AtomSubstVal? For that to work, we need another combinator,
68+
-- that lifts a SubstReader AtomSubstVal into a SubstReader Name, because
69+
-- effectsSubstE is currently typed as SubstReader AtomSubstVal.
70+
-- Then we can presumably recode substNonlin as `onNonLin substM`. We may
71+
-- be able to do that anyway, except we will then need to restrict the type
72+
-- of substNonlin to require `SubstE AtomSubstVal e`; but that may be fine.
73+
onNonLin :: HasCallStack
74+
=> TransposeM' i o a -> TransposeM i o a
75+
onNonLin cont = do
76+
subst <- getSubst
77+
let subst' = newSubst (\v -> case subst ! v of
78+
RenameNonlin v' -> Rename v'
79+
_ -> error "not a nonlinear expression")
80+
liftSubstReaderT $ runSubstReaderT subst' cont
81+
6382
isLin :: HoistableE e => e i -> TransposeM i o Bool
6483
isLin e = do
6584
substVals <- mapM lookupSubstM $ freeAtomVarsList e
@@ -123,10 +142,9 @@ substExprIfNonlin expr =
123142
isLin expr >>= \case
124143
True -> return Nothing
125144
False -> do
126-
expr' <- substNonlin expr
127-
getEffects expr' >>= isLinEff >>= \case
145+
onNonLin (getEffectsSubst expr) >>= isLinEff >>= \case
128146
True -> return Nothing
129-
False -> return $ Just expr'
147+
False -> Just <$> substNonlin expr
130148

131149
isLinEff :: EffectRow o -> TransposeM i o Bool
132150
isLinEff effs@(EffectRow _ Nothing) = do

0 commit comments

Comments
 (0)