typelevel / cats-mtl

cats transformer type classes.
https://typelevel.org/cats-mtl/
Other
307 stars 61 forks source link

Different Ask typeclass requirements in a same stack monad #537

Closed worekleszczy closed 8 months ago

worekleszczy commented 8 months ago

Hello,

I have a question how to deal with a different ask value requirements in the same monad stack. Imagine a situation that you have 2 actions that require different data accessible by Ask typeclass and want to integrate those under a single effect F[_] eg:

  case class ContextOne()
  case class ContextTwo()
  case class Context(one: ContextOne, two: ContextTwo)
  case class User(id: String, name: String)
  def actionOne[F[_]: Monad]()(implicit ask: Ask[F, ContextOne]): F[User] = ???
  def actionTwo[F[_]: Monad](implicit ask: Ask[F, ContextTwo]): F[Unit]   = ???
  def program[F[_]: Monad](implicit ask: Ask[F, ContextOne], aks2: Ask[F, ContextTwo]): F[Unit] = {
    for {
      _ <- actionOne[F]
      _ <- actionTwo[F]
    } yield ()
  }

  def run = {
    type App[Z] = Kleisli[IO, Context, Z]

    program[App] // no instances for Ask[F, ContextOne] nor Ask[F, ContextTwo]
  }

I assume that I could create a typeclass instance for both Ask[F, ContextOne] and Ask[F, ContextTwo] based on an instance I get for App type, but I just can't shake off the feeling that I'm doing something wrong here 😅. Are there any good practices established for those scenarios? Maybe having two Ask typeclasses is, in general, an indication of bad design? Any help would be appreciated 🙃

armanbilge commented 8 months ago

Check out this PR:

It lets you do something like:

implicit val local1 = Local[App, Context].map(_.one)
implicit val local2 = Local[App, Context].map(_.two)

Unfortunately that PR hasn't been released yet 😅 but I can work on that now. You can use the snapshot in the meantime.

Let me know if that works!

worekleszczy commented 8 months ago

Thank @armanbilge - I've taken a look at the PR you suggested and it seems that it solves precisely the issue I'm having! Can't wait until it's released. I'm closing this issue then 🙃

armanbilge commented 8 months ago

https://github.com/typelevel/cats-mtl/releases/tag/v1.4.0