testLocal :: [Int]
testLocal =
execWriter . flip runReaderT 1 . runT_ . construct . local (+ 1) $ do
r <- ask
tell [r]
yield r
r' <- ask
tell [r']
evaluates to [2,1]; i.e. local only applies to the first ask.
The problem is that in the definition of local:
local f m = PlanT $ \kp ke kr kf -> local f (runPlanT m kp ke kr kf)
base monad's local is only applied to the outermost monadic layer produced. That is, since r in PlanT is specialized to Step k o (MachineT m k o) in construct, the ‘result’ of the computation can actually contain other layers of the base monad within it, which are unaffected by local. Thus, second ask in the example above produces the original environment, since it is ‘hidden’ within the Yield constructor.
This function:
evaluates to
[2,1]
; i.e.local
only applies to the firstask
.The problem is that in the definition of
local
:base monad's
local
is only applied to the outermost monadic layer produced. That is, sincer
inPlanT
is specialized toStep k o (MachineT m k o)
inconstruct
, the ‘result’ of the computation can actually contain other layers of the base monad within it, which are unaffected bylocal
. Thus, secondask
in the example above produces the original environment, since it is ‘hidden’ within theYield
constructor.