Open ivan-timokhin opened 6 years ago
Thanks for reporting this. Don't have much time ATM to fix it (I wrote that instance years ago). Did you find out a fix in the meantime?
Best I can do is to steal the idea from similar monad in Control.Monad.Trans.Free.Church
(free
package). There, pass
and local
both internally convert the argument to a non-CPS representation, work on it, and then convert back (local
does something much more interesting, which I don't understand yet).
The idea, then, is to introduce a non-CPS version of PlanT
, implement pass
and listen
for it, and then use it internally in PlanT
versions.
This evaluates to
[1]
:while the same function sans
runT . construct
(i.e. working directly onWriterT
) evaluates to[1,1]
.Likewise, with
pass
, this evaluates to[1]
:while the
WriterT
version evaluates to[]
.I've grouped them in a single issue since the cause is very similar. In the definitions of
listen
andpass
(with some manual inlining)both
listen
andpass
from the base monad are applied toreturn x
, which hasmempty
as its accumulated writer state. Solisten
now always returnsmempty
, andpass
only operates onmempty
, leaving actual state accumulated in the provided action unchanged.