Cats: Consider Reader-style instance for MonoidK of Kleisli

Created on 25 Sep 2017  路  17Comments  路  Source: typelevel/cats

The current instance of MonoidK for Kleisli (which I will refer to as Endo instance) looks like:

implicit def instance[F[_]](implicit M: Monad[F]): MonoidK[位[伪 => Kleisli[F, 伪, 伪]]]

as opposed to what I'd call a Reader instance :

implicit def instance[F[_], A](implicit F: SemigroupK[F]): SemigroupK[Kleisli[F, A, ?]]

which imo should be preferred.

Concrete, driving use case
In http4s, we need to model an http service as Kleisli[OptionT[F, ?], Request, Response], and the proposed instance would allow composing services with <+>, getting the correct prioritised choice behaviour.

Rationale
An instance for Kleisli[A, ?] is more general than one for 位[伪 => Kleisli[F, 伪, 伪]], and therefore should be _the_ instance, using a newtype for the other one. This is consistent with both Scalaz and Haskell, where A => B gets instances and A => A gets newtyped as Endo, and also internally consistent with the other instances for Kleisli, which are prevalently Reader style.

There is some discussion about this in #247, but I believe the use case in http4s is important enough to reconsider

@rossabaker

Source Breaking

All 17 comments

cc @edmundnoble @ceedubs @non

I can obviously open a PR as well if this gets approved

Agree. The "EndoT" instance is interesting but I don't think it should be the default one. In scalaz I believe you get there via Endomorphic[Kleisli[F, ?, ?], A].

Before http4s is used as the justification for this, @aeons is changing the HttpService type as described to ensure it works as well on the full project as it worked in my REPL. But I think this is the right thing to do regardless.

@ChristopherDavenport offered to implement it if we decide to proceed.

I also agree that the second instance is more useful in general. I'm a bit afraid of too many breaking changes in RC1 but I think this one should be quite minor and not a big issue for most :)

The point of 1.0.0-MF is to identify breaking changes needed by the community before we go 1.0.

big +1 on this.

Looks like we should proceed with it. @ChristopherDavenport still interested?

  • Ticket that would render this moot: #1932
  • Related, stalled ticket: #1098

I'm worried that we can't change this instance in place without changing behavior silently for users.

I think silently breaking users is possible but probably rare. Someone would have to have an endo which also has a MonoidK on the inner type, and that MonoidK would need to be in scope.

I'd be surprised if even one person will be in this boat.

Don't Either and Option fall under this? That seems common.

I'm interested, and will get an initial version up this evening.

I can update #1098 if needed?

Yeah it seems like most of the code is already in #1098

Cool, I can back down in favor of an existing PR.

Added in #1098

Was this page helpful?
0 / 5 - 0 ratings