A handful of months ago, I brought the monad of no return proposal to discourse, and now many months later I bring what I hope will be my last question regarding one issue with one part of the proposal.
TL;DR: I’m looking for examples of fixes of memory leaks or issues about memory leaks due to the default definition of (*>)
.
To summarise the intent of the proposal, there are methods between the Applicative
and Monad
type classes that should always behave identically, if the type they are defined on is lawful. These methods can therefore be “canonically” defined: return = pure
, and (>>) = (*>)
. We wish to get rid of the redundancy here, and make these the top level definitions.
There is an issue with (>>) = (*>)
specifically, however. Currently, (>>)
is defined as (>>) a b = a >>= \_ -> b
(which I’ll alternatively call thenM
), while (*>) a b = (id <$ a) <*> b
(which I’ll call thenA
). In making (>>)
be equivalent to its canonical definition (so, (>>) = (*>)
), we’d be changing its default definition for virtually every Monad
in existence, and there have been issues with the definition of (*>)
in the past. One example of that can be found in issue 33 of the transformers package. The common problem seems to be that the definition thenA
leaks some amount of memory, but we’re unclear as to why.
My personal theory is this: only in the cases of monad transformers (or equivalents) will we see these performance regressions. If this is the case, then potential regressions industry wide are very low compared to the alternative worst case.
I’m therefore looking for more examples of badly behaved default (*>)
definitions. If they’re transformer-like, that’s good to have more examples, but if they’re not transformer-like, I’m especially interested.
If you want to ask more about the proposal(s), I’m also happy to answer those questions here.