Repository: 7mind/izumi
Pull request #1234 (2020-09-18 20:09:28)

Add missing BIOParallel's Monad syntax


Patch:
diff --git a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/BIORoot.scala b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/BIORoot.scala
index adb6324c6..fee94c755 100644
--- a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/BIORoot.scala
+++ b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/BIORoot.scala
@@ -23,7 +23,7 @@ object BIORoot extends BIORootInstancesLowPriority1 {
   @inline implicit final def AttachBIOFork3[FR[-_, +_, +_]](@unused self: BIOFunctor3[FR])(implicit BIOFork: BIOFork3[FR]): BIOFork.type = BIOFork
   @inline implicit final def AttachBlockingIO3[FR[-_, +_, +_]](@unused self: BIOFunctor3[FR])(implicit BlockingIO: BlockingIO3[FR]): BlockingIO.type = BlockingIO
 
-  implicit final class KleisliSyntaxAttached[FR[-_, +_, +_]](private val FR0: BIOFunctor3[FR]) extends AnyVal {
+  implicit final class KleisliSyntaxAttached[FR[-_, +_, +_]](@unused private val FR0: BIOFunctor3[FR]) extends AnyVal {
     @inline def fromKleisli[R, E, A](k: Kleisli[FR[Any, E, ?], R, A])(implicit FR: BIOMonadAsk[FR]): FR[R, E, A] = FR.fromKleisli(k)
     @inline def toKleisli[R, E, A](fr: FR[R, E, A])(implicit FR: BIOLocal[FR]): Kleisli[FR[Any, E, ?], R, A] = FR.toKleisli(fr)
   }
diff --git a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/syntax/BIO3Syntax.scala b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/syntax/BIO3Syntax.scala
index 7ed3d7b4d..742c1589e 100644
--- a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/syntax/BIO3Syntax.scala
+++ b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/syntax/BIO3Syntax.scala
@@ -244,6 +244,8 @@ object BIO3Syntax {
   trait BIO3ImplicitPuns2 extends BIO3ImplicitPuns3 {
     @inline implicit final def BIOParallel3[FR[-_, +_, +_]: BIOParallel3, R, E, A](self: FR[R, E, A]): BIO3Syntax.BIOParallel3Ops[FR, R, E, A] =
       new BIO3Syntax.BIOParallel3Ops[FR, R, E, A](self)
+    @inline implicit final def BIOParallel3[F[-_, +_, +_]: BIOMonad3, R, E, A](self: F[R, E, A]): BIO3Syntax.BIOMonad3Ops[F, R, E, A] =
+      new BIO3Syntax.BIOMonad3Ops[F, R, E, A](self)
     @inline final def BIOParallel3[FR[-_, +_, +_]: BIOParallel3]: BIOParallel3[FR] = implicitly
   }
   trait BIO3ImplicitPuns3 extends BIO3ImplicitPuns4 {
diff --git a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/syntax/BIOSyntax.scala b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/syntax/BIOSyntax.scala
index 9a4bcbd1e..59518ce80 100644
--- a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/syntax/BIOSyntax.scala
+++ b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/bio/syntax/BIOSyntax.scala
@@ -190,6 +190,7 @@ object BIOSyntax {
   }
   trait BIOImplicitPuns2 extends BIOImplicitPuns3 {
     @inline implicit final def BIOParallel[F[+_, +_]: BIOParallel, E, A](self: F[E, A]): BIOSyntax.BIOParallelOps[F, E, A] = new BIOSyntax.BIOParallelOps[F, E, A](self)
+    @inline implicit final def BIOParallel[F[+_, +_]: BIOMonad, E, A](self: F[E, A]): BIOSyntax.BIOMonadOps[F, E, A] = new BIOSyntax.BIOMonadOps[F, E, A](self)
     @inline final def BIOParallel[F[+_, +_]: BIOParallel]: BIOParallel[F] = implicitly
   }
   trait BIOImplicitPuns3 extends BIOImplicitPuns4 {


Test patch:
diff --git a/fundamentals/fundamentals-bio/src/test/scala/izumi/fundamentals/bio/test/BIOSyntaxTest.scala b/fundamentals/fundamentals-bio/src/test/scala/izumi/fundamentals/bio/test/BIOSyntaxTest.scala
index 1680e750f..6037f725b 100644
--- a/fundamentals/fundamentals-bio/src/test/scala/izumi/fundamentals/bio/test/BIOSyntaxTest.scala
+++ b/fundamentals/fundamentals-bio/src/test/scala/izumi/fundamentals/bio/test/BIOSyntaxTest.scala
@@ -1,14 +1,14 @@
 package izumi.fundamentals.bio.test
 
-import izumi.functional.bio.{BIO, BIOArrow, BIOAsk, BIOBifunctor3, BIOError, BIOFork, BIOFork3, BIOFunctor, BIOLocal, BIOMonad, BIOMonad3, BIOMonadAsk, BIOPrimitives, BIOPrimitives3, BIOProfunctor, BIOTemporal, BIOTemporal3, F}
 import monix.bio
 import org.scalatest.wordspec.AnyWordSpec
-import zio.Has
 
 import scala.concurrent.duration._
 
 class BIOSyntaxTest extends AnyWordSpec {
 
+  implicit val clock: zio.clock.Clock = zio.Has(zio.clock.Clock.Service.live)
+
   "BIOParallel.zipPar/zipParLeft/zipParRight/zipWithPar is callable" in {
     import izumi.functional.bio.BIOParallel
 
@@ -25,6 +25,7 @@ class BIOSyntaxTest extends AnyWordSpec {
 
   "BIOParallel3.zipPar/zipParLeft/zipParRight/zipWithPar is callable" in {
     import izumi.functional.bio.BIOParallel3
+
     def x[F[-_, +_, +_]: BIOParallel3](a: F[Any, Nothing, Unit], b: F[Any, Nothing, Unit]) = {
       a.zipPar(b)
       a.zipParLeft(b)
@@ -38,6 +39,7 @@ class BIOSyntaxTest extends AnyWordSpec {
 
   "BIOAsync.race is callable along with all BIOParallel syntax" in {
     import izumi.functional.bio.BIOAsync
+
     def x[F[+_, +_]: BIOAsync](a: F[Nothing, Unit], b: F[Nothing, Unit]) = {
       a zipPar b
       a zipParLeft b
@@ -67,6 +69,8 @@ class BIOSyntaxTest extends AnyWordSpec {
   }
 
   "BIO.apply is callable" in {
+    import izumi.functional.bio.BIO
+
     class X[F[+_, +_]: BIO] {
       def hello = BIO(println("hello world!"))
     }
@@ -76,6 +80,8 @@ class BIOSyntaxTest extends AnyWordSpec {
   }
 
   "BIO.widen/widenError is callable" in {
+    import izumi.functional.bio.{BIO, F}
+
     def x[F[+_, +_]: BIO]: F[Throwable, AnyVal] = {
       identity[F[Throwable, AnyVal]] {
         F.pure(None: Option[Int]).flatMap {
@@ -90,7 +96,7 @@ class BIOSyntaxTest extends AnyWordSpec {
   }
 
   "BIOBracket.bracketCase & guaranteeCase are callable" in {
-    import izumi.functional.bio.{BIOBracket, BIOExit}
+    import izumi.functional.bio.{BIOBracket, BIOExit, F}
 
     def x[F[+_, +_]: BIOBracket]: F[Throwable, Int] = {
       F.pure(None).bracketCase(release = {
@@ -128,6 +134,8 @@ class BIOSyntaxTest extends AnyWordSpec {
   }
 
   "BIO.when/unless/ifThenElse have nice inference" in {
+    import izumi.functional.bio.{BIOMonad, F}
+
     def x[F[+_, +_]: BIOMonad] = {
       F.ifThenElse(F.pure(false): F[RuntimeException, Boolean])(F.pure(()), F.pure(()): F[Throwable, Any]) *>
       F.when(F.pure(false): F[RuntimeException, Boolean])(F.pure(()): F[Throwable, Unit])
@@ -137,6 +145,8 @@ class BIOSyntaxTest extends AnyWordSpec {
   }
 
   "withFilter test" in {
+    import izumi.functional.bio.{BIOError, F}
+
     def x[F[+_, +_]: BIOError]: F[NoSuchElementException, Unit] = {
       assertDoesNotCompile(
         """
@@ -177,6 +187,8 @@ class BIOSyntaxTest extends AnyWordSpec {
   }
 
   "F / FR summoners examples" in {
+    import izumi.functional.bio.{BIOFork, BIOFork3, BIOFunctor, BIOMonad, BIOMonad3, BIOPrimitives, BIOPrimitives3, BIOTemporal, F}
+
     def x[F[+_, +_]: BIOMonad] = {
       F.when(false)(F.unit)
     }
@@ -200,7 +212,6 @@ class BIOSyntaxTest extends AnyWordSpec {
       F.mkRef(4).flatMap(r => r.update(_ + 5) *> r.get.map(_ - 1)).fork.flatMap(_.join)
     }
     lazy val zioTest = {
-      implicit val zioClock: zio.clock.Clock = Has(zio.clock.Clock.Service.live)
       (
         x[zio.IO],
         y[zio.IO],
@@ -220,6 +231,7 @@ class BIOSyntaxTest extends AnyWordSpec {
 
   "Support BIO syntax for ZIO with wildcard import" in {
     import izumi.functional.bio._
+
     zio.IO.effectTotal(List(4)).flatMap {
       F.traverse(_)(_ => zio.IO.unit)
     } *> F.unit
@@ -228,6 +240,8 @@ class BIOSyntaxTest extends AnyWordSpec {
   }
 
   "FR: Local/Ask summoners examples" in {
+    import izumi.functional.bio.{BIOArrow, BIOAsk, BIOBifunctor3, BIOLocal, BIOMonad3, BIOMonadAsk, BIOProfunctor, BIOTemporal3, F}
+
     def x[FR[-_, +_, +_]: BIOMonad3: BIOAsk] = {
       F.unit *> F.ask[Int].map {
         _: Int =>
@@ -312,13 +326,33 @@ class BIOSyntaxTest extends AnyWordSpec {
         }.toKleisli
       }.provide(4).flatMap(_ => F.unit).widenError[Throwable].leftMap(identity)
     }
-    def docExamples() = {
-      import izumi.functional.bio.{BIOMonad, BIOMonadAsk, BIOPrimitives, BIORef3, F}
 
+    lazy val _ = (
+      x[zio.ZIO],
+      onlyMonadAsk[zio.ZIO],
+      onlyMonadAskAccess[zio.ZIO],
+      onlyAsk[zio.ZIO],
+      y[zio.ZIO],
+      arrowAsk[zio.ZIO],
+      profunctorOnly[zio.ZIO],
+      biotemporalPlusLocal[zio.ZIO],
+      biomonadPlusLocal[zio.ZIO],
+      bifunctorOnly[zio.ZIO],
+    )
+  }
+
+  "doc examples" in {
+    locally {
+      import izumi.functional.bio.{BIOMonad, BIOPrimitives, F}
       def adder[F[+_, +_]: BIOMonad: BIOPrimitives](i: Int): F[Nothing, Int] =
         F.mkRef(0)
           .flatMap(ref => ref.update(_ + i) *> ref.get)
 
+      lazy val _ = adder[zio.IO](1)
+    }
+
+    locally {
+      import izumi.functional.bio.{BIOMonadAsk, BIORef3, F}
       // update ref from the environment and return result
       def adderEnv[F[-_, +_, +_]: BIOMonadAsk](i: Int): F[BIORef3[F, Int], Nothing, Int] =
         F.access {
@@ -328,24 +362,8 @@ class BIOSyntaxTest extends AnyWordSpec {
               res <- ref.get
             } yield res
         }
-      lazy val _ = (
-        adder[zio.IO](1),
-        adderEnv[zio.ZIO](1),
-      )
+
+      lazy val _ = adderEnv[zio.ZIO](1)
     }
-    implicit val clock: zio.clock.Clock = zio.Has(zio.clock.Clock.Service.live)
-    lazy val _ = (
-      x[zio.ZIO],
-      onlyMonadAsk[zio.ZIO],
-      onlyMonadAskAccess[zio.ZIO],
-      onlyAsk[zio.ZIO],
-      y[zio.ZIO],
-      arrowAsk[zio.ZIO],
-      profunctorOnly[zio.ZIO],
-      biotemporalPlusLocal[zio.ZIO],
-      biomonadPlusLocal[zio.ZIO],
-      bifunctorOnly[zio.ZIO],
-      docExamples(),
-    )
   }
 }