Closed jwiegley closed 7 years ago
Pinging @snoyberg, whose monad-unlift
library aims at solving some of the consequences of this problem.
Are there examples of a commutative monad which doesn't fit into MonadUnlift
?
WriterT
-- where the accumulator is a commutative monoid -- since in that case StM m a
is not equivalent to a
, as it holds the accumulated value from the action.
This should have been obvious to me, but IO
is not commutative, so my notes here may not apply as I had thought before.
Imagine we have some Monad
m
, we can easily use the Applicative to do something like:However, using
MonadBaseControl
, we cannot safely lift an operation like this through a base monad:The reason is that in
combineM
,x
andy
are executed independently from each other, and then their contexts are recombined, rather than executing within a single, new context.It turns out that this works for commutative monads, just not for non-commutative ones. Thus, functions like
concurrently
fromlifted-async
become dangerous to use, because there is no type-checking done to guard against using non-commutative monads.I'm not sure what the best solution to this problem is, other than having a new set of "law only" type classes to identity the monads we can safely use in such operations:
Now we can safely lift
concurrently
:I'm opening this issue to invite discussion on this.