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

Missing Async instance for arbitrary environment #497

Closed
IndiscriminateCoding opened this issue Jan 31, 2022 · 2 comments
Closed

Missing Async instance for arbitrary environment #497

IndiscriminateCoding opened this issue Jan 31, 2022 · 2 comments

Comments

@IndiscriminateCoding
Copy link

Right now there is no (implicit runtime based) instance for arbitrary environment type.
That's very unfortunate as I'm forced reimplement whole CE3 typeclass hierarchy in every project which doesn't use Has-based environments (so, no Clock and Blocking).
Here is what I'm using for now:

package zio.wtf

import cats.effect._
import zio.blocking.Blocking
import zio.clock.Clock
import zio.interop.catz._
import zio.{ Promise, RIO, Runtime }

import scala.concurrent.ExecutionContext
import scala.concurrent.duration.FiniteDuration

class ZIOAsyncRuntime[R](implicit rts: Runtime[Clock with Blocking]) extends Async[RIO[R, *]] {
  type F[A] = RIO[R, A]

  def sleep(time: FiniteDuration): F[Unit] =
    temporalInstance.sleep(time).provide(rts.environment)
  val monotonic: F[FiniteDuration] = temporalInstance.monotonic.provide(rts.environment)
  val realTime: F[FiniteDuration] = temporalInstance.realTime.provide(rts.environment)

  def pure[A](x: A): F[A] = concurrentInstance.pure(x)
  def handleErrorWith[A](fa: F[A])(f: Throwable => F[A]): F[A] =
    concurrentInstance.handleErrorWith(fa)(f)
  def raiseError[A](e: Throwable): F[A] = concurrentInstance.raiseError(e)
  def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] = concurrentInstance.flatMap(fa)(f)
  def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] = concurrentInstance.tailRecM(a)(f)
  def deferred[A]: F[Deferred[F, A]] = concurrentInstance.deferred[A]
  def ref[A](a: A): F[Ref[F, A]] = concurrentInstance.ref(a)
  def cede: F[Unit] = concurrentInstance.cede
  override def never[A]: F[A] = concurrentInstance.never
  def start[A](fa: F[A]): F[Fiber[F, Throwable, A]] = concurrentInstance.start(fa)
  def canceled: F[Unit] = concurrentInstance.canceled
  def forceR[A, B](fa: F[A])(fb: F[B]): F[B] = concurrentInstance.forceR(fa)(fb)
  def onCancel[A](fa: F[A], fin: F[Unit]): F[A] = concurrentInstance.onCancel(fa, fin)
  def uncancelable[A](body: Poll[F] => F[A]): F[A] = concurrentInstance.uncancelable(body)
  override def unique: F[Unique.Token] = concurrentInstance.unique
  def cont[K, R](body: Cont[F, K, R]): F[R] = Async.defaultCont(body)(this)
  override def async[A](k: (Either[Throwable, A] => Unit) => F[Option[F[Unit]]]): F[A] =
    Promise.make[Nothing, Unit].flatMap { promise =>
      RIO.effectAsyncM { register =>
        k(either => register(promise.await *> RIO.fromEither(either))) *> promise.succeed(())
      }
    }
  override def async_[A](k: (Either[Throwable, A] => Unit) => Unit): F[A] =
    RIO.effectAsync(register => k(register.compose(fromEither)))
  def evalOn[A](fa: F[A], ec: ExecutionContext): F[A] = fa.on(ec)
  def executionContext: F[ExecutionContext] = RIO.executor.map(_.asEC)
  def suspend[A](hint: Sync.Type)(thunk: => A): F[A] =
    asyncRuntimeInstance.suspend(hint)(thunk)
}
@joroKr21
Copy link
Contributor

I'm a bit confused - you do use Runtime[Clock with Blocking]

@IndiscriminateCoding
Copy link
Author

@joroKr21

I'm a bit confused - you do use Runtime[Clock with Blocking]

Yes, that's the point - resulting instance allows arbitrary R

neko-kai added a commit to 7mind/interop-cats that referenced this issue Feb 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants