Move Data.Functor.Contravariant into base

The typeclass Contravariant (from the contravariant package) is both useful and fundamental. I would like to see this moved into base. One additional motivating factor is that it would become possible for a DeriveContravariant extension to be written in a future GHC release. I'd love to hear other people's thoughts, even if it's as simple as a yea or nay. Thanks. -Andrew Martin

Putting Contravariant in base sounds like a reasonable thing to do.
It's a pretty basic class.
Deriving Contravariant seems a bit tricky. If Contravariant is in base
and part of the deriving code, what Functor/Contravariant instances do
you derive for e.g. newtype Compose f g a = Compose (f (g a))?
Shachaf
On Sun, Dec 11, 2016 at 8:14 AM, Andrew Martin
The typeclass Contravariant (from the contravariant package) is both useful and fundamental. I would like to see this moved into base. One additional motivating factor is that it would become possible for a DeriveContravariant extension to be written in a future GHC release. I'd love to hear other people's thoughts, even if it's as simple as a yea or nay. Thanks.
-Andrew Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

That's a good point about the deriving ambiguity. I had not really thought that through all the way. Additionally, I just stumbled across https://github.com/ekmett/contravariant/issues/17, which makes it pretty clear that there actually isn't a good way to handle all cases. I think that it might still be nice to have a DeriveContravariant that is simply weaker than DeriveFunctor. It could just complain and error out in ambiguous cases. The ambiguous cases would be all types parameterized by more than one higher-kinded type. And DeriveFunctor could just be left alone, continuing to derive the Functor instance for Compose the same way it already does. Usually, when I write Contravariant instances, it's for stuff like this that doesn't even involve anything higher-kinded: data Encoding c a = Encoding (Vector (c, a -> c)) Of course, I could be totally wrong about the rule I suggested for figuring out ambiguous cases. I guess I probably need to think about it more. Regardless, I'm glad to hear that someone else is in favor of moving Contravariant into base. On Sun, Dec 11, 2016 at 12:05:05PM -0800, Shachaf Ben-Kiki wrote:
Putting Contravariant in base sounds like a reasonable thing to do. It's a pretty basic class.
Deriving Contravariant seems a bit tricky. If Contravariant is in base and part of the deriving code, what Functor/Contravariant instances do you derive for e.g. newtype Compose f g a = Compose (f (g a))?
Shachaf
On Sun, Dec 11, 2016 at 8:14 AM, Andrew Martin
wrote: The typeclass Contravariant (from the contravariant package) is both useful and fundamental. I would like to see this moved into base. One additional motivating factor is that it would become possible for a DeriveContravariant extension to be written in a future GHC release. I'd love to hear other people's thoughts, even if it's as simple as a yea or nay. Thanks.
-Andrew Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I have no particular issue with moving Contravariant into base.
That said, DeriveContravariant doesn't work out as well as you'd think. See
the discussion in here: https://github.com/ekmett/contravariant/issues/17
(There were other, longer discussions elsewhere that were er.. more of a
discussion, but they were mostly on places like #haskell-lens which aren't
logged and I can't find them at the moment.)
With covariance you can just ignore that contravariant cases exist and get
reasonable deriving.
With contravariance composition of contravariant functors is covariant. You
have the f (g a) problem. Which of the two is contravariant? This doesn't
arise solely from type arguments. When faced with a concrete data type, you
can't just look for a Contravariant or Functor instance for it, because
both might be available (think Proxy). So the whole extension becomes a
bug-addled mess.
e.g. There are two sensible Contravariant instances for Compose, but
neither one is canonical.
The other DeriveFoo definitions all do reasonable things. This can't do a
reasonable thing in any non-trivial situation.
-Edward
On Sun, Dec 11, 2016 at 11:14 AM, Andrew Martin
The typeclass Contravariant (from the contravariant package) is both useful and fundamental. I would like to see this moved into base. One additional motivating factor is that it would become possible for a DeriveContravariant extension to be written in a future GHC release. I'd love to hear other people's thoughts, even if it's as simple as a yea or nay. Thanks.
-Andrew Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

The deriving problem is annoying indeed. I stumbled across that github issue shortly after proposing this change. The only sensible thing I can think of for a DeriveContravariant would be to only allow it if a data type were only parameterized by things that were not higher-kinded. I'm guessing that this is what you are describing when you say: The other DeriveFoo definitions all do reasonable things. This can't do a reasonable thing in any non-trivial situation. Although I think that those "trivial situations" are common enough that a necessarily imperfect DeriveContravariant could still be useful. Regardless, it's the move into base that I care more about, so I'm glad to hear that you find that agreeable. -Andrew Martin On Tue, Dec 13, 2016 at 01:35:57PM -0500, Edward Kmett wrote:
I have no particular issue with moving Contravariant into base.
That said, DeriveContravariant doesn't work out as well as you'd think. See the discussion in here: https://github.com/ekmett/contravariant/issues/17 (There were other, longer discussions elsewhere that were er.. more of a discussion, but they were mostly on places like #haskell-lens which aren't logged and I can't find them at the moment.)
With covariance you can just ignore that contravariant cases exist and get reasonable deriving.
With contravariance composition of contravariant functors is covariant. You have the f (g a) problem. Which of the two is contravariant? This doesn't arise solely from type arguments. When faced with a concrete data type, you can't just look for a Contravariant or Functor instance for it, because both might be available (think Proxy). So the whole extension becomes a bug-addled mess.
e.g. There are two sensible Contravariant instances for Compose, but neither one is canonical.
The other DeriveFoo definitions all do reasonable things. This can't do a reasonable thing in any non-trivial situation.
-Edward
On Sun, Dec 11, 2016 at 11:14 AM, Andrew Martin
wrote: The typeclass Contravariant (from the contravariant package) is both useful and fundamental. I would like to see this moved into base. One additional motivating factor is that it would become possible for a DeriveContravariant extension to be written in a future GHC release. I'd love to hear other people's thoughts, even if it's as simple as a yea or nay. Thanks.
-Andrew Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

-1. I think to move something into base there should be some hard evidence for its popularity. Such could be provided by a reverse dependency search on hackage. --Andreas On 11.12.2016 17:14, Andrew Martin wrote:
The typeclass Contravariant (from the contravariant package) is both useful and fundamental. I would like to see this moved into base. One additional motivating factor is that it would become possible for a DeriveContravariant extension to be written in a future GHC release. I'd love to hear other people's thoughts, even if it's as simple as a yea or nay. Thanks.
-Andrew Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/

Just to articulate a few more points on each side:
To Andreas point, one issue with contravariant in base is that there are no
types in base that would serve as reasonable instances. You'd get a
scattershot pile of mostly 'nonsensical' instances for stuff like the
GHC.Generics types.
On the other hand, but a far lesser concern, it'd shed the dependencies the
package has, which would be good for things like lens-style Getters which
use the constraint. Being able to use or supply more types of lenses with
no dependencies is a minor good point.
On the other other hand, rehoming a lot of the 'nonsensical' style
instances to the packages that have their dependencies inverted is a fair
chunk of work.
On the other other other hand, this would fix the weird dependency
inversion between StateVar and contravariant forced by the haskell platform.
Er... that is a lot of hands. I personally don't care much one way or the
other. Doing nothing is literally the default option. If there winds a lot
of noise against this I'm happy to stick with the status quo, which is not
THAT broken. On the other other other other hand, if there is a huge upwell
of support, we could make a go of it.
-Edward
Note to self: I need to stop counting hands in unary.
On Tue, Dec 13, 2016 at 3:34 PM, Andreas Abel
-1. I think to move something into base there should be some hard evidence for its popularity. Such could be provided by a reverse dependency search on hackage.
--Andreas
On 11.12.2016 17:14, Andrew Martin wrote:
The typeclass Contravariant (from the contravariant package) is both useful and fundamental. I would like to see this moved into base. One additional motivating factor is that it would become possible for a DeriveContravariant extension to be written in a future GHC release. I'd love to hear other people's thoughts, even if it's as simple as a yea or nay. Thanks.
-Andrew Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden
andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On 2016-12-13 04:45 PM, Edward Kmett wrote:
To Andreas point, one issue with contravariant in base is that there are no types in base that would serve as reasonable instances. You'd get a scattershot pile of mostly 'nonsensical' instances for stuff like the GHC.Generics types.
We could add a non-nonsensical¹ instance easily enough:
newtype Flip f a b = Flip {flipBack :: f b a}
instance Contravariant (Flip (->) a) where contramap f (Flip g) = Flip (g . f)
Or, if FlexibleInstances are a problem:
newtype Inverse a b = Inverse {applyInverse :: b -> a}
instance Contravariant (Inverse a) where contramap f (Inverse g) = Inverse (g . f)
(¹): apparently sensical is not a word, which is nonsensible

The reverse dependency count can be found here: http://packdeps.haskellers.com/reverse The contravariant library has 73 reverse dependencies. Just as a reference point, bifunctors currently has 112 dependencies, and Data.Bifunctor was moved into base-4.9. Whether or not you believe that 73 reverse deps is sufficient is up to you, but those are the most relevant numbers I can provide. -Andrew Martin On Tue, Dec 13, 2016 at 09:34:13PM +0100, Andreas Abel wrote:
-1. I think to move something into base there should be some hard evidence for its popularity. Such could be provided by a reverse dependency search on hackage.
--Andreas
On 11.12.2016 17:14, Andrew Martin wrote:
The typeclass Contravariant (from the contravariant package) is both useful and fundamental. I would like to see this moved into base. One additional motivating factor is that it would become possible for a DeriveContravariant extension to be written in a future GHC release. I'd love to hear other people's thoughts, even if it's as simple as a yea or nay. Thanks.
-Andrew Martin _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden
andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
participants (5)
-
Andreas Abel
-
Andrew Martin
-
Edward Kmett
-
Mario Blažević
-
Shachaf Ben-Kiki