package wow.doge.mygame import cats.data.ReaderT import monix.bio.UIO import org.scalatest.funsuite.AnyFunSuite import monix.execution.Scheduler.Implicits.global import monix.bio.IO import cats.mtl.Ask import cats.mtl.implicits._ import cats.effect.LiftIO import monix.bio.Task import cats.data.Kleisli import monix.bio.IOLift class ReaderT_Test extends AnyFunSuite { // type IoReaderT[S, E, A] = ReaderT[UIO, S, Either[E, A]] // val IoReaderT = ReaderT // val t = // ReaderT[UIO, String, Either[Error, Unit]](s => UIO.unit.attempt) // .run("s") // .rethrow // val r: IoReaderT[String, Error, Unit] = IoReaderT(s => UIO.unit.attempt) // val t2 = r.run("s").rethrow // Kleisli[IO, String, Unit](s => IO.unit) case class Environment(str: String, num: Int) // test("runReaderT_Test") { // def fun1: ReaderT[UIO, String, Unit] = ReaderT(str => UIO(println(str))) // def fun2: ReaderT[UIO, Int, Unit] = ReaderT(num => UIO(println(num))) // def total: ReaderT[UIO, Environment, Unit] = // for { // _ <- fun1.local[Environment](_.str) // _ <- fun2.local[Environment](_.num) // } yield () // val uio: UIO[Unit] = total.run(Environment("hello", 50)) // uio.runSyncUnsafe() // } implicit val L = new LiftIO[ReaderT[IO[String, ?], Environment, *]] { override def liftIO[A]( ioa: cats.effect.IO[A] ): ReaderT[IO[String, ?], Environment, A] = ReaderT(_ => IO.from(ioa).onErrorHandleWith(_ => IO.raiseError("whew"))) // override def liftIO[A](ioa: cats.effect.IO[A]): monix.bio.Task[A] = // Task.from(ioa) } implicit val L2 = new IOLift[ReaderT[IO[String, ?], Environment, *]] { override def apply[A]( task: monix.bio.Task[A] ): ReaderT[IO[String, ?], Environment, A] = ReaderT(_ => IO.from(task).onErrorHandleWith(_ => IO.raiseError("whew"))) } sealed trait AppError type RIO[S, E, A] = ReaderT[IO[E, ?], S, A] type EIO[S, A] = RIO[S, AppError, A] type AppIO[A] = RIO[Environment, AppError, A] test("2") { def fun1: RIO[String, String, Unit] = ReaderT(s => IO(println(s)).onErrorHandleWith(_ => IO.raiseError("wow"))) def fun2: ReaderT[IO[String, ?], Int, Unit] = ReaderT(num => IO(println(num)).onErrorHandleWith(_ => IO.raiseError("whew")) ) def fun3: ReaderT[IO[String, ?], Environment, Unit] = for { env <- ReaderT.ask[IO[String, ?], Environment] } yield () def test[F[_]]()(implicit A: Ask[F, Int]) = A.ask[Int] // def synctest[F[_]] def fun4: ReaderT[IO[String, ?], Environment, Unit] = for { env <- ReaderT.ask[IO[String, ?], Environment] _ <- ReaderT.liftF( IO(println(env)).onErrorHandleWith(_ => IO.raiseError("wow")) ) _ <- fun3 } yield () val topkek = test[ReaderT[IO[String, ?], Int, *]]().local[Environment](_.num) def app: ReaderT[IO[String, ?], Environment, Unit] = for { _ <- fun1.local[Environment](_.str) _ <- fun2.local[Environment](_.num) _ <- fun3 _ <- fun4 _ <- topkek } yield () val io: IO[String, Unit] = app.run(Environment("hello", 50)) io.attempt.runSyncUnsafe() } }