Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cats' Ask and Local without ZEnvironment #685

Merged
merged 3 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package zio.interop

import cats.implicits.*
import cats.mtl.laws.discipline.*
import cats.mtl.{ Handle, Raise }
import zio.*
import zio.interop.catz.*
import zio.interop.catz.mtl.*
Expand All @@ -13,11 +12,21 @@ class CatsMtlSpec extends ZioSpecBase {

checkAllAsync(
"Ask[ZIO[Ctx, Error, _]]",
implicit tc => AskTests[ZIO[Ctx, Error, _], ZEnvironment[Ctx]].ask[Ctx]
implicit tc => AskTests[ZIO[Ctx, Error, _], Ctx].ask[Ctx]
)

checkAllAsync(
"Local[ZIO[Ctx, Error, _]]",
implicit tc => LocalTests[ZIO[Ctx, Error, _], Ctx].local[Ctx, Int]
)

checkAllAsync(
"Ask[ZIO[Ctx, Error, _]] with ZEnvironment",
implicit tc => AskTests[ZIO[Ctx, Error, _], ZEnvironment[Ctx]].ask[Ctx]
)

checkAllAsync(
"Local[ZIO[Ctx, Error, _]] with ZEnvironment",
implicit tc => LocalTests[ZIO[Ctx, Error, _], ZEnvironment[Ctx]].local[ZEnvironment[Ctx], Int]
)

Expand All @@ -44,7 +53,4 @@ class CatsMtlSpec extends ZioSpecBase {
"Handle[ZIO[Ctx, Error, _]]",
implicit tc => HandleTests[ZIO[Ctx, Error, _], Error].handle[Int]
)

def raiseSummoner[R, E] = Raise[ZIO[R, E, _], E]
def handleSummoner[R, E] = Handle[ZIO[R, E, _], E]
}
55 changes: 40 additions & 15 deletions zio-interop-cats/shared/src/main/scala/zio/interop/catsmtl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,35 @@ package zio.interop

import cats.Applicative
import cats.mtl.*
import zio.{ CanFail, FiberRef, ZEnvironment, ZIO }
import zio.{ CanFail, FiberRef, Tag, ZEnvironment, ZIO }
import zio.internal.stacktracer.InteropTracer

abstract class CatsMtlPlatform extends CatsMtlInstances

abstract class CatsMtlInstances {
abstract class CatsMtlInstances extends CatsMtlInstances1 {
implicit def zioHandle[R, E](implicit ev: Applicative[ZIO[R, E, _]]): Handle[ZIO[R, E, _], E] =
new Handle[ZIO[R, E, _], E] {
override def applicative: Applicative[ZIO[R, E, _]] = ev
override def raise[E2 <: E, A](e: E2): ZIO[R, E, A] = ZIO.fail(e)
override def handleWith[A](fa: ZIO[R, E, A])(f: E => ZIO[R, E, A]): ZIO[R, E, A] =
fa.catchAll(f)(implicitly[CanFail[E]], InteropTracer.newTrace(f))
}

implicit def zioLocal[R, E](implicit ev: Applicative[ZIO[R, E, _]]): Local[ZIO[R, E, _], ZEnvironment[R]] =
implicit def zioZEnvLocal[R, E](implicit ev: Applicative[ZIO[R, E, _]]): Local[ZIO[R, E, _], ZEnvironment[R]] =
new Local[ZIO[R, E, _], ZEnvironment[R]] {
override def applicative: Applicative[ZIO[R, E, _]] = ev
override def ask[E2 >: ZEnvironment[R]]: ZIO[R, E, E2] = ZIO.environment
override def applicative: Applicative[ZIO[R, E, _]] = ev

override def ask[E2 >: ZEnvironment[R]]: ZIO[R, E, E2] = ZIO.environment

override def local[A](fa: ZIO[R, E, A])(f: ZEnvironment[R] => ZEnvironment[R]): ZIO[R, E, A] =
fa.provideSomeEnvironment(f)(InteropTracer.newTrace(f))
}

implicit def zioAsk[R1, R <: R1, E](implicit ev: Applicative[ZIO[R, E, _]]): Ask[ZIO[R, E, _], ZEnvironment[R1]] =
implicit def zioZEnvAsk[R1, R <: R1, E](implicit ev: Applicative[ZIO[R, E, _]]): Ask[ZIO[R, E, _], ZEnvironment[R1]] =
new Ask[ZIO[R, E, _], ZEnvironment[R1]] {
override def applicative: Applicative[ZIO[R, E, _]] = ev
override def ask[R2 >: ZEnvironment[R1]]: ZIO[R, E, R2] = ZIO.environment
}
override def applicative: Applicative[ZIO[R, E, _]] = ev

implicit def zioHandle[R, E](implicit ev: Applicative[ZIO[R, E, _]]): Handle[ZIO[R, E, _], E] =
new Handle[ZIO[R, E, _], E] {
override def applicative: Applicative[ZIO[R, E, _]] = ev
override def raise[E2 <: E, A](e: E2): ZIO[R, E, A] = ZIO.fail(e)
override def handleWith[A](fa: ZIO[R, E, A])(f: E => ZIO[R, E, A]): ZIO[R, E, A] =
fa.catchAll(f)(implicitly[CanFail[E]], InteropTracer.newTrace(f))
override def ask[R2 >: ZEnvironment[R1]]: ZIO[R, E, R2] = ZIO.environment
}

implicit def fiberRefLocal[R, E](implicit
Expand All @@ -65,3 +67,26 @@ abstract class CatsMtlInstances {
}

}

trait CatsMtlInstances1 {
implicit def zioLocal[R: Tag, E](implicit ev: Applicative[ZIO[R, E, _]]): Local[ZIO[R, E, _], R] =
new Local[ZIO[R, E, _], R] {
override def applicative: Applicative[ZIO[R, E, _]] = ev

override def ask[R1 >: R]: ZIO[R, E, R1] = ZIO.environment[R].map(_.get)

override def local[A](fa: ZIO[R, E, A])(f: R => R): ZIO[R, E, A] =
fa.provideSomeEnvironment({ (env: ZEnvironment[R]) =>
env.update(f)
})(InteropTracer.newTrace(f))
}

implicit def zioAsk[R1: Tag, R <: R1, E](implicit
ev: Applicative[ZIO[R, E, _]]
): Ask[ZIO[R, E, _], R1] =
new Ask[ZIO[R, E, _], R1] {
override def applicative: Applicative[ZIO[R, E, _]] = ev

override def ask[R2 >: R1]: ZIO[R, E, R2] = ZIO.environment[R1].map(_.get)
}
}
Loading