Give MonadTrans a QuantifiedConstraints superclass

This is to advertise the proposal (https://gitlab.haskell.org/ghc/ghc/-/issues/19922) to add a superclass to the MonadTrans type class in Control.Monad.Trans. A Monad transformer 'trans' lifts a 'Monad m' to a 'Monad (trans m)'. This proposal code-ifies that with a superclass constraint: class (forall m. Monad m => Monad (trans m)) => MonadTrans trans where .. This is the main motiviating example of the Quantified Class Constraints paper https://gkaracha.github.io/papers/quantcs.pdf

On Wed, 2 Jun 2021, Baldur Blöndal wrote:
This is to advertise the proposal (https://gitlab.haskell.org/ghc/ghc/-/issues/19922) to add a superclass to the MonadTrans type class in Control.Monad.Trans.
A Monad transformer 'trans' lifts a 'Monad m' to a 'Monad (trans m)'.
This proposal code-ifies that with a superclass constraint:
class (forall m. Monad m => Monad (trans m)) => MonadTrans trans where ..
This is the main motiviating example of the Quantified Class Constraints paper https://gkaracha.github.io/papers/quantcs.pdf
So far, 'transformers' is mostly Haskell 98. This is why I prefer it to 'mtl'. Wouldn't it be enough to add this extension to 'mtl'? I see that 'mtl' re-uses the MonadTrans class from 'transformers' but maybe it should define its own class with the quantified constraints then.

On Wed, Jun 02, 2021 at 07:27:28AM +0200, Henning Thielemann wrote:
So far, 'transformers' is mostly Haskell 98. This is why I prefer it to 'mtl'. Wouldn't it be enough to add this extension to 'mtl'? I see that 'mtl' re-uses the MonadTrans class from 'transformers' but maybe it should define its own class with the quantified constraints then.
I don't think that having two incompatible MonadTrans classes would constitute progress. Older versions of the transformers library (which is by now quite stable) will continue to be available, for anyone who wants to use a Haskell '98 (ish?) version. [ FWIW, I don't know what you mean by "is mostly Haskell '98", I'd expect that to be a strict binary choice: is or isn't. ] -- Viktor.

I feel like instead, MonadTrans should have a function
(>>==) :: Monad m => t m a -> (a -> t m b) -> t m b
That way, it can prove it's a Monad while still staying Haskell 98.
On Wed, Jun 2, 2021, 10:51 Viktor Dukhovni
On Wed, Jun 02, 2021 at 07:27:28AM +0200, Henning Thielemann wrote:
So far, 'transformers' is mostly Haskell 98. This is why I prefer it to 'mtl'. Wouldn't it be enough to add this extension to 'mtl'? I see that 'mtl' re-uses the MonadTrans class from 'transformers' but maybe it should define its own class with the quantified constraints then.
I don't think that having two incompatible MonadTrans classes would constitute progress. Older versions of the transformers library (which is by now quite stable) will continue to be available, for anyone who wants to use a Haskell '98 (ish?) version.
[ FWIW, I don't know what you mean by "is mostly Haskell '98", I'd expect that to be a strict binary choice: is or isn't. ]
-- Viktor. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

That sounds like a nice idea. Which laws would we require for it? The
usual monad laws require a pure too right? Along with fmap?
Does this necessitate the existence of applicative trans?
On Wed, Jun 2, 2021 at 12:06 PM Zemyla
I feel like instead, MonadTrans should have a function
(>>==) :: Monad m => t m a -> (a -> t m b) -> t m b
That way, it can prove it's a Monad while still staying Haskell 98.
On Wed, Jun 2, 2021, 10:51 Viktor Dukhovni
wrote: On Wed, Jun 02, 2021 at 07:27:28AM +0200, Henning Thielemann wrote:
So far, 'transformers' is mostly Haskell 98. This is why I prefer it to 'mtl'. Wouldn't it be enough to add this extension to 'mtl'? I see that 'mtl' re-uses the MonadTrans class from 'transformers' but maybe it should define its own class with the quantified constraints then.
I don't think that having two incompatible MonadTrans classes would constitute progress. Older versions of the transformers library (which is by now quite stable) will continue to be available, for anyone who wants to use a Haskell '98 (ish?) version.
[ FWIW, I don't know what you mean by "is mostly Haskell '98", I'd expect that to be a strict binary choice: is or isn't. ]
-- Viktor. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

return is lift . return. Upon reflection, I believe (though may be
mistaken) that every MonadTrans is also an instance of a hypothetical
FunctorTrans class, only requiring a Functor constraint to be a
Functor itself; however, ApplicativeTrans doesn't work because StateT
among others requires a Monad constraint to be an Applicative.
On Wed, Jun 2, 2021 at 6:41 PM Carter Schonwald
That sounds like a nice idea. Which laws would we require for it? The usual monad laws require a pure too right? Along with fmap?
Does this necessitate the existence of applicative trans?
On Wed, Jun 2, 2021 at 12:06 PM Zemyla
wrote: I feel like instead, MonadTrans should have a function
(>>==) :: Monad m => t m a -> (a -> t m b) -> t m b
That way, it can prove it's a Monad while still staying Haskell 98.
On Wed, Jun 2, 2021, 10:51 Viktor Dukhovni
wrote: On Wed, Jun 02, 2021 at 07:27:28AM +0200, Henning Thielemann wrote:
So far, 'transformers' is mostly Haskell 98. This is why I prefer it to 'mtl'. Wouldn't it be enough to add this extension to 'mtl'? I see that 'mtl' re-uses the MonadTrans class from 'transformers' but maybe it should define its own class with the quantified constraints then.
I don't think that having two incompatible MonadTrans classes would constitute progress. Older versions of the transformers library (which is by now quite stable) will continue to be available, for anyone who wants to use a Haskell '98 (ish?) version.
[ FWIW, I don't know what you mean by "is mostly Haskell '98", I'd expect that to be a strict binary choice: is or isn't. ]
-- Viktor. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

+1 to the original proposal of using QuantifiedConstraints.
There is no need to stick to the standard from 23 years ago, and having two
different classes is only likely to bring confusion and extra work for
library maintainers.
Adding `(>>==) :: Monad m => t m a -> (a -> t m b) -> t m b` seems even
worse; it will break every single instance of MonadTrans in the ecosystem!
2021年6月3日(木) 9:45 Zemyla
return is lift . return. Upon reflection, I believe (though may be mistaken) that every MonadTrans is also an instance of a hypothetical FunctorTrans class, only requiring a Functor constraint to be a Functor itself; however, ApplicativeTrans doesn't work because StateT among others requires a Monad constraint to be an Applicative.
On Wed, Jun 2, 2021 at 6:41 PM Carter Schonwald
wrote: That sounds like a nice idea. Which laws would we require for it? The
usual monad laws require a pure too right? Along with fmap?
Does this necessitate the existence of applicative trans?
On Wed, Jun 2, 2021 at 12:06 PM Zemyla
wrote: I feel like instead, MonadTrans should have a function
(>>==) :: Monad m => t m a -> (a -> t m b) -> t m b
That way, it can prove it's a Monad while still staying Haskell 98.
On Wed, Jun 2, 2021, 10:51 Viktor Dukhovni
wrote:
On Wed, Jun 02, 2021 at 07:27:28AM +0200, Henning Thielemann wrote:
So far, 'transformers' is mostly Haskell 98. This is why I prefer it to 'mtl'. Wouldn't it be enough to add this extension to 'mtl'? I see that 'mtl' re-uses the MonadTrans class from 'transformers' but maybe it should define its own class with the quantified constraints then.
I don't think that having two incompatible MonadTrans classes would constitute progress. Older versions of the transformers library (which is by now quite stable) will continue to be available, for anyone who wants to use a Haskell '98 (ish?) version.
[ FWIW, I don't know what you mean by "is mostly Haskell '98", I'd expect that to be a strict binary choice: is or isn't. ]
-- Viktor. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Thu, 3 Jun 2021, Fumiaki Kinoshita wrote:
+1 to the original proposal of using QuantifiedConstraints.
There is no need to stick to the standard from 23 years ago, and having two different classes is only likely to bring confusion and extra work for library maintainers.
But why do we have the separation between 'transformers' and 'mtl' then?

On Wed, Jun 2, 2021 at 11:07 PM Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Thu, 3 Jun 2021, Fumiaki Kinoshita wrote:
+1 to the original proposal of using QuantifiedConstraints.
There is no need to stick to the standard from 23 years ago, and having two different classes is only likely to bring confusion and extra work for library maintainers.
But why do we have the separation between 'transformers' and 'mtl' then?
We have it though a combination of intent and historical accident. Originally there was just `mtl`-1. Then `transformers` + (`monads-fd` | `monads-tf`) came along with a couple of also-ran packages like Galois' `monadLib`. The ecosystem splintered badly and nobody could work with anybody in a different splinter. To merge the `mtl` portion of the ecosystem with the monads-fd ecosystem, we renamed the latter to `mtl`-2, and the `monads-tf` corner of the ecosystem silently died because nobody was using it and it conflicted in the module names with things that people did use. `transformers` was then sort of retroactively justified for two reasons, one to provide a "simple" core, then-Haskell98ish package like you suggest. `transformers` has supported things like PolyKinds for a long time, leans on StandaloneDeriving, etc. so it isn't exactly the first chink in that first justification's armor. Another justification was to supply a common base for experimentation on things like `monads-fd` and `monads-tf` and all the gajillion effect-system-alikes that have been built on top that do things like replace the `MonadFoo` classes with ones that use type families or tags or remove the functional dependencies. The latter mission remains intact. -Edward _______________________________________________
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

+1 to the quantified constraint. It would be nice to be able to talk
about monad transformer composition.
Cheers,
George
On Thu, 3 Jun 2021 at 19:08, Edward Kmett
On Wed, Jun 2, 2021 at 11:07 PM Henning Thielemann
wrote: On Thu, 3 Jun 2021, Fumiaki Kinoshita wrote:
+1 to the original proposal of using QuantifiedConstraints.
There is no need to stick to the standard from 23 years ago, and having two different classes is only likely to bring confusion and extra work for library maintainers.
But why do we have the separation between 'transformers' and 'mtl' then?
We have it though a combination of intent and historical accident.
Originally there was just `mtl`-1. Then `transformers` + (`monads-fd` | `monads-tf`) came along with a couple of also-ran packages like Galois' `monadLib`. The ecosystem splintered badly and nobody could work with anybody in a different splinter. To merge the `mtl` portion of the ecosystem with the monads-fd ecosystem, we renamed the latter to `mtl`-2, and the `monads-tf` corner of the ecosystem silently died because nobody was using it and it conflicted in the module names with things that people did use.
`transformers` was then sort of retroactively justified for two reasons, one to provide a "simple" core, then-Haskell98ish package like you suggest.
`transformers` has supported things like PolyKinds for a long time, leans on StandaloneDeriving, etc. so it isn't exactly the first chink in that first justification's armor.
Another justification was to supply a common base for experimentation on things like `monads-fd` and `monads-tf` and all the gajillion effect-system-alikes that have been built on top that do things like replace the `MonadFoo` classes with ones that use type families or tags or remove the functional dependencies.
The latter mission remains intact.
-Edward
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Wed, Jun 2, 2021 at 9:06 AM Zemyla
I feel like instead, MonadTrans should have a function
(>>==) :: Monad m => t m a -> (a -> t m b) -> t m b
This strikes me as a strictly worse outcome. Now you get coherence laws relating (>>==) to a (>>=) that may or may not exist that you have to keep track of, but get nothing enforcing anything, can't delegate to code that builds off Monad, leading to random code duplication, and users are hoist on the horns of the dilemma of using (>>=) or (>>==) with different constraints in each circumstance. -Edward
That way, it can prove it's a Monad while still staying Haskell 98.
On Wed, Jun 2, 2021, 10:51 Viktor Dukhovni
wrote: On Wed, Jun 02, 2021 at 07:27:28AM +0200, Henning Thielemann wrote:
So far, 'transformers' is mostly Haskell 98. This is why I prefer it to 'mtl'. Wouldn't it be enough to add this extension to 'mtl'? I see that 'mtl' re-uses the MonadTrans class from 'transformers' but maybe it should define its own class with the quantified constraints then.
I don't think that having two incompatible MonadTrans classes would constitute progress. Older versions of the transformers library (which is by now quite stable) will continue to be available, for anyone who wants to use a Haskell '98 (ish?) version.
[ FWIW, I don't know what you mean by "is mostly Haskell '98", I'd expect that to be a strict binary choice: is or isn't. ]
-- Viktor. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Thu, Jun 03, 2021 at 10:12:01AM +0900, Fumiaki Kinoshita wrote:
+1 to the original proposal of using QuantifiedConstraints.
There is no need to stick to the standard from 23 years ago, and having two different classes is only likely to bring confusion and extra work for library maintainers.
Adding `(>>==) :: Monad m => t m a -> (a -> t m b) -> t m b` seems even worse; it will break every single instance of MonadTrans in the ecosystem!
+1. Yes, as much as one might fondly remember C '89, Perl 4, Python 2, Haskell 98, ... the 90's are long over, and it is time to let go. On Wed, Jun 02, 2021 at 06:05:20PM -0700, Edward Kmett wrote:
I feel like instead, MonadTrans should have a function
(>>==) :: Monad m => t m a -> (a -> t m b) -> t m b
This strikes me as a strictly worse outcome. Now you get coherence laws relating (>>==) to a (>>=) that may or may not exist that you have to keep track of, but get nothing enforcing anything, can't delegate to code that builds off Monad, leading to random code duplication, and users are hoist on the horns of the dilemma of using (>>=) or (>>==) with different constraints in each circumstance.
+1. -- Viktor.

On Wed, 2 Jun 2021, Viktor Dukhovni wrote:
[ FWIW, I don't know what you mean by "is mostly Haskell '98", I'd expect that to be a strict binary choice: is or isn't. ]
It uses some LANGUAGE pragmas internally like Safe, AutoDerivable, CPP, but the external API is Haskell 98.
participants (8)
-
Baldur Blöndal
-
Carter Schonwald
-
Edward Kmett
-
Fumiaki Kinoshita
-
George Wilson
-
Henning Thielemann
-
Viktor Dukhovni
-
Zemyla