diff --git a/.jvmopts b/.jvmopts
index 83ed6fb401..0ca1262c38 100644
--- a/.jvmopts
+++ b/.jvmopts
@@ -1,4 +1,3 @@
-# see https://weblogs.java.net/blog/kcpeppe/archive/2013/12/11/case-study-jvm-hotspot-flags
-Dfile.encoding=UTF8
-Xms1G
-Xmx6G
@@ -6,7 +5,5 @@
-XX:ReservedCodeCacheSize=250M
-XX:+TieredCompilation
-XX:-UseGCOverheadLimit
-# effectively adds GC to Perm space
-XX:+CMSClassUnloadingEnabled
-# must be enabled for CMSClassUnloadingEnabled to work
-XX:+UseConcMarkSweepGC
diff --git a/build.sbt b/build.sbt
index b13c61d389..3bf80f81af 100644
--- a/build.sbt
+++ b/build.sbt
@@ -67,7 +67,7 @@ lazy val commonJsSettings = Seq(
scalaJSStage in Global := FastOptStage,
parallelExecution := false,
requiresDOM := false,
- jsEnv := NodeJSEnv().value,
+ jsEnv := new org.scalajs.jsenv.nodejs.NodeJSEnv(),
// Only used for scala.js for now
botBuild := scala.sys.env.get("TRAVIS").isDefined,
// batch mode decreases the amount of memory needed to compile scala.js code
diff --git a/core/src/main/scala/cats/data/EitherT.scala b/core/src/main/scala/cats/data/EitherT.scala
index c9e5e3a531..b95c67df0e 100644
--- a/core/src/main/scala/cats/data/EitherT.scala
+++ b/core/src/main/scala/cats/data/EitherT.scala
@@ -175,7 +175,7 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) {
* scala> val v1: Validated[NonEmptyList[Error], Int] = Validated.invalidNel("error 1")
* scala> val v2: Validated[NonEmptyList[Error], Int] = Validated.invalidNel("error 2")
* scala> val eithert: EitherT[Option, Error, Int] = EitherT.leftT[Option, Int]("error 3")
- * scala> eithert.withValidated { v3 => (v1 |@| v2 |@| v3.toValidatedNel).map { case (i, j, k) => i + j + k } }
+ * scala> eithert.withValidated { v3 => (v1, v2, v3.toValidatedNel).mapN { case (i, j, k) => i + j + k } }
* res0: EitherT[Option, NonEmptyList[Error], Int] = EitherT(Some(Left(NonEmptyList(error 1, error 2, error 3))))
* }}}
*/
diff --git a/core/src/main/scala/cats/data/OneAnd.scala b/core/src/main/scala/cats/data/OneAnd.scala
index 8e7728004c..9d85b8d8e5 100644
--- a/core/src/main/scala/cats/data/OneAnd.scala
+++ b/core/src/main/scala/cats/data/OneAnd.scala
@@ -229,10 +229,10 @@ private[data] trait OneAndLowPriority3 extends OneAndLowPriority2 {
implicit def catsDataNonEmptyTraverseForOneAnd[F[_]](implicit F: Traverse[F], F2: MonadCombine[F]): NonEmptyTraverse[OneAnd[F, ?]] =
new NonEmptyReducible[OneAnd[F, ?], F] with NonEmptyTraverse[OneAnd[F, ?]] {
def nonEmptyTraverse[G[_], A, B](fa: OneAnd[F, A])(f: (A) => G[B])(implicit G: Apply[G]): G[OneAnd[F, B]] = {
- import cats.syntax.cartesian._
+ import cats.syntax.apply._
fa.map(a => Apply[G].map(f(a))(OneAnd(_, F2.empty[B])))(F)
- .reduceLeft(((acc, a) => (acc |@| a).map((x: OneAnd[F, B], y: OneAnd[F, B]) => x.combine(y))))
+ .reduceLeft(((acc, a) => (acc, a).mapN((x: OneAnd[F, B], y: OneAnd[F, B]) => x.combine(y))))
}
diff --git a/core/src/main/scala/cats/data/Tuple2K.scala b/core/src/main/scala/cats/data/Tuple2K.scala
index 7543da0172..1c1b5c1c51 100644
--- a/core/src/main/scala/cats/data/Tuple2K.scala
+++ b/core/src/main/scala/cats/data/Tuple2K.scala
@@ -2,7 +2,6 @@ package cats
package data
import cats.functor.Contravariant
-import cats.syntax.cartesian._
/**
* [[Tuple2K]] is a product to two independent functor values.
@@ -159,8 +158,8 @@ private[data] sealed trait Tuple2KTraverse[F[_], G[_]] extends Traverse[λ[α =>
def F: Traverse[F]
def G: Traverse[G]
- override def traverse[H[_]: Applicative, A, B](fa: Tuple2K[F, G, A])(f: A => H[B]): H[Tuple2K[F, G, B]] =
- (F.traverse(fa.first)(f) |@| G.traverse(fa.second)(f)).map(Tuple2K(_, _))
+ override def traverse[H[_], A, B](fa: Tuple2K[F, G, A])(f: A => H[B])(implicit H: Applicative[H]): H[Tuple2K[F, G, B]] =
+ H.map2(F.traverse(fa.first)(f), G.traverse(fa.second)(f))(Tuple2K(_, _))
}
private[data] sealed trait Tuple2KMonadCombine[F[_], G[_]] extends MonadCombine[λ[α => Tuple2K[F, G, α]]]
diff --git a/core/src/main/scala/cats/syntax/all.scala b/core/src/main/scala/cats/syntax/all.scala
index 0cf3dad050..5352b51183 100644
--- a/core/src/main/scala/cats/syntax/all.scala
+++ b/core/src/main/scala/cats/syntax/all.scala
@@ -43,7 +43,6 @@ trait AllSyntax
with TraverseFilterSyntax
with TraverseSyntax
with NonEmptyTraverseSyntax
- with TupleSyntax
with ValidatedSyntax
with VectorSyntax
with WriterSyntax
diff --git a/core/src/main/scala/cats/syntax/apply.scala b/core/src/main/scala/cats/syntax/apply.scala
index 17f9685aaf..32854d57c7 100644
--- a/core/src/main/scala/cats/syntax/apply.scala
+++ b/core/src/main/scala/cats/syntax/apply.scala
@@ -1,7 +1,7 @@
package cats
package syntax
-trait ApplySyntax {
+trait ApplySyntax extends TupleCartesianSyntax {
implicit final def catsSyntaxApply[F[_], A](fa: F[A])(implicit F: Apply[F]): Apply.Ops[F, A] =
new Apply.Ops[F, A] {
val self = fa
diff --git a/core/src/main/scala/cats/syntax/cartesian.scala b/core/src/main/scala/cats/syntax/cartesian.scala
index c5c4b6bb79..abb69f05ad 100644
--- a/core/src/main/scala/cats/syntax/cartesian.scala
+++ b/core/src/main/scala/cats/syntax/cartesian.scala
@@ -10,6 +10,8 @@ trait CartesianSyntax {
}
abstract class CartesianOps[F[_], A] extends Cartesian.Ops[F, A] {
+
+ @deprecated("Replaced by an apply syntax, e.g. instead of (a |@| b).map(...) use (a, b).mapN(...)", "1.0.0-MF")
final def |@|[B](fb: F[B]): CartesianBuilder[F]#CartesianBuilder2[A, B] =
new CartesianBuilder[F] |@| self |@| fb
diff --git a/core/src/main/scala/cats/syntax/package.scala b/core/src/main/scala/cats/syntax/package.scala
index 7c7ab4285e..bef1b4174f 100644
--- a/core/src/main/scala/cats/syntax/package.scala
+++ b/core/src/main/scala/cats/syntax/package.scala
@@ -43,7 +43,6 @@ package object syntax {
object traverse extends TraverseSyntax
object nonEmptyTraverse extends NonEmptyTraverseSyntax
object traverseFilter extends TraverseFilterSyntax
- object tuple extends TupleSyntax
object validated extends ValidatedSyntax
object vector extends VectorSyntax
object writer extends WriterSyntax
diff --git a/core/src/main/scala/cats/syntax/tuple.scala b/core/src/main/scala/cats/syntax/tuple.scala
deleted file mode 100644
index 2448e6f3bc..0000000000
--- a/core/src/main/scala/cats/syntax/tuple.scala
+++ /dev/null
@@ -1,4 +0,0 @@
-package cats
-package syntax
-
-trait TupleSyntax extends TupleCartesianSyntax
diff --git a/docs/src/main/tut/datatypes/freeapplicative.md b/docs/src/main/tut/datatypes/freeapplicative.md
index 5c0448c24f..3c7788cdfa 100644
--- a/docs/src/main/tut/datatypes/freeapplicative.md
+++ b/docs/src/main/tut/datatypes/freeapplicative.md
@@ -46,7 +46,7 @@ of a for-comprehension. We can however still use `Applicative` syntax provided b
```tut:silent
import cats.implicits._
-val prog: Validation[Boolean] = (size(5) |@| hasNumber).map { case (l, r) => l && r}
+val prog: Validation[Boolean] = (size(5), hasNumber).mapN { case (l, r) => l && r}
```
As it stands, our program is just an instance of a data structure - nothing has happened
@@ -139,7 +139,7 @@ def logValidation[A](validation: Validation[A]): List[String] =
```tut:book
logValidation(prog)
logValidation(size(5) *> hasNumber *> size(10))
-logValidation((hasNumber |@| size(3)).map(_ || _))
+logValidation((hasNumber, size(3)).mapN(_ || _))
```
### Why not both?
diff --git a/docs/src/main/tut/datatypes/validated.md b/docs/src/main/tut/datatypes/validated.md
index 55c7303940..bb258b147b 100644
--- a/docs/src/main/tut/datatypes/validated.md
+++ b/docs/src/main/tut/datatypes/validated.md
@@ -205,7 +205,7 @@ implicit def validatedApplicative[E : Semigroup]: Applicative[Validated[E, ?]] =
```
Awesome! And now we also get access to all the goodness of `Applicative`, which includes `map{2-22}`, as well as the
-`Cartesian` syntax `|@|`.
+`Cartesian` tuple syntax.
We can now easily ask for several bits of configuration and get any and all errors returned back.
diff --git a/docs/src/main/tut/faq.md b/docs/src/main/tut/faq.md
index e1219525ff..a2458a9a28 100644
--- a/docs/src/main/tut/faq.md
+++ b/docs/src/main/tut/faq.md
@@ -203,7 +203,6 @@ All other symbols can be imported with `import cats.implicits._`
| Symbol | Name | Nickname | Type Class | Signature |
| -------------------------------- | ---------------------- | ---------------- | ----------------------- | --------------------------------------------------------- |
-| fa |@| fb
| Cartesian builder | Cinnabon, scream | `Cartesian[F[_]]` | |@|(fa: F[A])(fb: F[B]): F[(A, B)]
|
| `fa *> fb` | right apply | | `Cartesian[F[_]]` | `*>(fa: F[A])(fb: F[B]): F[A]` |
| `fa <* fb` | left apply | | `Cartesian[F[_]]` | `<*(fa: F[A])(fb: F[B]): F[B]` |
| `x === y` | equals | | `Eq[A]` | `eqv(x: A, y: A): Boolean` |
diff --git a/docs/src/main/tut/typeclasses/applicative.md b/docs/src/main/tut/typeclasses/applicative.md
index b4c26cf9d0..4c6cea3ef5 100644
--- a/docs/src/main/tut/typeclasses/applicative.md
+++ b/docs/src/main/tut/typeclasses/applicative.md
@@ -264,15 +264,15 @@ val o2: Option[String] = Some("hello")
```
```tut:book
-(o1 |@| o2).map((i: Int, s: String) => i.toString ++ s)
-(o1 |@| o2).tupled
+(o1, o2).mapN((i: Int, s: String) => i.toString ++ s)
+(o1, o2).tupled
```
The second expects the effects in a tuple and works by enriching syntax on top of the existing
`TupleN` types.
```tut:book
-(o1, o2).map2((i: Int, s: String) => i.toString ++ s)
+(o1, o2).mapN((i: Int, s: String) => i.toString ++ s)
```
## Further Reading
diff --git a/docs/src/main/tut/typeclasses/invariantmonoidal.md b/docs/src/main/tut/typeclasses/invariantmonoidal.md
index 4525cd6655..fbf103df8f 100644
--- a/docs/src/main/tut/typeclasses/invariantmonoidal.md
+++ b/docs/src/main/tut/typeclasses/invariantmonoidal.md
@@ -52,8 +52,8 @@ import cats.implicits._
case class Foo(a: String, c: List[Double])
implicit val fooSemigroup: Semigroup[Foo] = (
- (implicitly[Semigroup[String]] |@| implicitly[Semigroup[List[Double]]])
- .imap(Foo.apply)(Function.unlift(Foo.unapply))
+ (implicitly[Semigroup[String]], implicitly[Semigroup[List[Double]]])
+ .imapN(Foo.apply)(Function.unlift(Foo.unapply))
)
```
@@ -105,7 +105,7 @@ trait CCProduct {
def read(s: CSV): (Option[(A, B)], CSV) = {
val (a1, s1) = fa.read(s)
val (a2, s2) = fb.read(s1)
- ((a1 |@| a2).map(_ -> _), s2)
+ ((a1, a2).mapN(_ -> _), s2)
}
def write(a: (A, B)): CSV =
@@ -163,15 +163,15 @@ def numericSystemCodec(base: Int): CsvCodec[Int] =
case class BinDec(binary: Int, decimal: Int)
val binDecCodec: CsvCodec[BinDec] = (
- (numericSystemCodec(2) |@| numericSystemCodec(10))
- .imap(BinDec.apply)(Function.unlift(BinDec.unapply))
+ (numericSystemCodec(2), numericSystemCodec(10))
+ .imapN(BinDec.apply)(Function.unlift(BinDec.unapply))
)
case class Foo(name: String, bd1: BinDec, bd2: BinDec)
val fooCodec: CsvCodec[Foo] = (
- (stringCodec |@| binDecCodec |@| binDecCodec)
- .imap(Foo.apply)(Function.unlift(Foo.unapply))
+ (stringCodec, binDecCodec, binDecCodec)
+ .imapN(Foo.apply)(Function.unlift(Foo.unapply))
)
```
diff --git a/free/src/test/scala/cats/free/FreeApplicativeTests.scala b/free/src/test/scala/cats/free/FreeApplicativeTests.scala
index 1e6467900b..afdef68074 100644
--- a/free/src/test/scala/cats/free/FreeApplicativeTests.scala
+++ b/free/src/test/scala/cats/free/FreeApplicativeTests.scala
@@ -73,7 +73,7 @@ class FreeApplicativeTests extends CatsSuite {
// fixed by #568
val fli1 = FreeApplicative.lift[List, Int](List(1, 3, 5, 7))
val fli2 = FreeApplicative.lift[List, Int](List(1, 3, 5, 7))
- (fli1 |@| fli2).map(_ + _)
+ (fli1, fli2).mapN(_ + _)
}
test("FreeApplicative#analyze") {
diff --git a/project/Boilerplate.scala b/project/Boilerplate.scala
index bbc587aecc..e3eeb9c1e0 100644
--- a/project/Boilerplate.scala
+++ b/project/Boilerplate.scala
@@ -136,6 +136,7 @@ object Boilerplate {
|
|import cats.functor.{Contravariant, Invariant}
|
+ |@deprecated("replaced by apply syntax", "1.0.0-MF")
|private[syntax] final class CartesianBuilder[F[_]] {
| def |@|[A](a: F[A]) = new CartesianBuilder1(a)
|
@@ -238,15 +239,21 @@ object Boilerplate {
val map =
if (arity == 1) s"def map[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F]): F[Z] = functor.map($tupleArgs)(f)"
- else s"def map$arity[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F], cartesian: Cartesian[F]): F[Z] = Cartesian.map$arity($tupleArgs)(f)"
+ else s"def mapN[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F]): F[Z] = Cartesian.map$arity($tupleArgs)(f)"
val contramap =
if (arity == 1) s"def contramap[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F]): F[Z] = contravariant.contramap($tupleArgs)(f)"
- else s"def contramap$arity[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F], cartesian: Cartesian[F]): F[Z] = Cartesian.contramap$arity($tupleArgs)(f)"
+ else s"def contramapN[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F]): F[Z] = Cartesian.contramap$arity($tupleArgs)(f)"
val imap =
if (arity == 1) s"def imap[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F]): F[Z] = invariant.imap($tupleArgs)(f)(g)"
- else s"def imap$arity[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F], cartesian: Cartesian[F]): F[Z] = Cartesian.imap$arity($tupleArgs)(f)(g)"
+ else s"def imapN[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F]): F[Z] = Cartesian.imap$arity($tupleArgs)(f)(g)"
+
+ val tupled = if (arity != 1) {
+ s"def tupled(implicit invariant: Invariant[F]): F[(${`A..N`})] = Cartesian.tuple$n($tupleArgs)"
+ } else {
+ ""
+ }
block"""
|package cats
@@ -255,13 +262,15 @@ object Boilerplate {
|import cats.functor.{Contravariant, Invariant}
|
|trait TupleCartesianSyntax {
- - implicit def catsSyntaxTuple${arity}Cartesian[F[_], ${`A..N`}]($tupleTpe): Tuple${arity}CartesianOps[F, ${`A..N`}] = new Tuple${arity}CartesianOps(t$arity)
+ - implicit def catsSyntaxTuple${arity}Cartesian[F[_], ${`A..N`}]($tupleTpe)(implicit C: Cartesian[F]): Tuple${arity}CartesianOps[F, ${`A..N`}] = new Tuple${arity}CartesianOps(t$arity, C)
|}
|
- -private[syntax] final class Tuple${arity}CartesianOps[F[_], ${`A..N`}]($tupleTpe) {
+ -private[syntax] final class Tuple${arity}CartesianOps[F[_], ${`A..N`}]($tupleTpe, C: Cartesian[F]) {
+ - implicit val cartesian: Cartesian[F] = C
- $map
- $contramap
- $imap
+ - $tupled
- def apWith[Z](f: F[(${`A..N`}) => Z])(implicit apply: Apply[F]): F[Z] = apply.ap$n(f)($tupleArgs)
-}
|
diff --git a/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalTests.scala b/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalTests.scala
index 3363c32fc8..9137f8d174 100644
--- a/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalTests.scala
+++ b/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalTests.scala
@@ -4,7 +4,7 @@ package tests
import cats.laws.discipline.eq.catsLawsEqForFn1
import cats.laws.discipline.{InvariantMonoidalTests, SerializableTests}
import cats.instances.all._
-import cats.syntax.cartesian._
+import cats.syntax.apply._
import cats.Eq
import org.scalacheck.{Arbitrary, Gen}
@@ -42,7 +42,7 @@ object CsvCodecInvariantMonoidalTests {
def read(s: CSV): (Option[(A, B)], CSV) = {
val (a1, s1) = fa.read(s)
val (a2, s2) = fb.read(s1)
- ((a1 |@| a2).map(_ -> _), s2)
+ ((a1, a2).mapN(_ -> _), s2)
}
def write(a: (A, B)): CSV =
diff --git a/tests/src/test/scala/cats/tests/ReaderWriterStateTTests.scala b/tests/src/test/scala/cats/tests/ReaderWriterStateTTests.scala
index fcd3d9c9b9..7af05125a6 100644
--- a/tests/src/test/scala/cats/tests/ReaderWriterStateTTests.scala
+++ b/tests/src/test/scala/cats/tests/ReaderWriterStateTTests.scala
@@ -204,7 +204,7 @@ class ReaderWriterStateTTests extends CatsSuite {
test("runEmpty, runEmptyS, runEmptyA and runEmptyL are consistent") {
forAll { (f: ReaderWriterStateT[Option, String, String, String, Int], c: String) =>
- (f.runEmptyL(c) |@| f.runEmptyS(c) |@| f.runEmptyA(c)).tupled should === (f.runEmpty(c))
+ (f.runEmptyL(c), f.runEmptyS(c), f.runEmptyA(c)).tupled should === (f.runEmpty(c))
}
}
diff --git a/tests/src/test/scala/cats/tests/SyntaxTests.scala b/tests/src/test/scala/cats/tests/SyntaxTests.scala
index d97902b7fb..f99472a8dc 100644
--- a/tests/src/test/scala/cats/tests/SyntaxTests.scala
+++ b/tests/src/test/scala/cats/tests/SyntaxTests.scala
@@ -193,28 +193,37 @@ object SyntaxTests extends AllInstances with AllSyntax {
val fb1: F[B] = fa.as(b)
}
- def testApply[F[_]: Apply, A, B, C, D, Z]: Unit = {
+ def testApply[F[_]: Apply : Cartesian, G[_]: Contravariant : Cartesian, H[_]: Invariant : Cartesian, A, B, C, D, E, Z] = {
+ val tfabc = mock[(F[A], F[B], F[C])]
val fa = mock[F[A]]
- val fab = mock[F[A => B]]
- val fb0: F[B] = fab.ap(fa)
-
val fb = mock[F[B]]
- val fabz = mock[F[(A, B) => Z]]
- val fz0: F[Z] = fabz.ap2(fa, fb)
+ val fc = mock[F[C]]
+ val f = mock[(A, B, C) => Z]
+ val ff = mock[F[(A, B, C) => Z]]
+
+ tfabc mapN f
+ (fa, fb, fc) mapN f
+ (fa, fb, fc) apWith ff
- val f = mock[(A, B) => Z]
- val fz1: F[Z] = fa.map2(fb)(f)
+ val tgabc = mock[(G[A], G[B])]
+ val ga = mock[G[A]]
+ val gb = mock[G[B]]
+ val g = mock[Z => (A, B)]
- val f1 = mock[(A, B) => Z]
- val ff1 = mock[F[(A, B) => Z]]
- val fz2: F[Z] = (fa |@| fb).map(f1)
- val fz3: F[Z] = (fa |@| fb).apWith(ff1)
+ tgabc contramapN g
+ (ga, gb) contramapN g
- val fc = mock[F[C]]
- val f2 = mock[(A, B, C) => Z]
- val ff2 = mock[F[(A, B, C) => Z]]
- val fz4: F[Z] = (fa |@| fb |@| fc).map(f2)
- val fz5: F[Z] = (fa |@| fb |@| fc).apWith(ff2)
+ val thabcde = mock[(H[A], H[B], H[C], H[D], H[E])]
+ val ha = mock[H[A]]
+ val hb = mock[H[B]]
+ val hc = mock[H[C]]
+ val hd = mock[H[D]]
+ val he = mock[H[E]]
+ val f5 = mock[(A, B, C, D, E) => Z]
+ val g5 = mock[Z => (A, B, C, D, E)]
+
+ thabcde.imapN(f5)(g5)
+ (ha, hb, hc, hd, he).imapN(f5)(g5)
}
def testBifoldable[F[_, _]: Bifoldable, A, B, C, D: Monoid]: Unit = {
@@ -293,38 +302,6 @@ object SyntaxTests extends AllInstances with AllSyntax {
val gea4 = ga.recoverWith(pfegea)
}
- def testTupleArity[F[_]: Apply : Cartesian, G[_]: Contravariant : Cartesian, H[_]: Invariant : Cartesian, A, B, C, D, E, Z] = {
- val tfabc = mock[(F[A], F[B], F[C])]
- val fa = mock[F[A]]
- val fb = mock[F[B]]
- val fc = mock[F[C]]
- val f = mock[(A, B, C) => Z]
- val ff = mock[F[(A, B, C) => Z]]
-
- tfabc map3 f
- (fa, fb, fc) map3 f
- (fa, fb, fc) apWith ff
-
- val tgabc = mock[(G[A], G[B])]
- val ga = mock[G[A]]
- val gb = mock[G[B]]
- val g = mock[Z => (A, B)]
-
- tgabc contramap2 g
- (ga, gb) contramap2 g
-
- val thabcde = mock[(H[A], H[B], H[C], H[D], H[E])]
- val ha = mock[H[A]]
- val hb = mock[H[B]]
- val hc = mock[H[C]]
- val hd = mock[H[D]]
- val he = mock[H[E]]
- val f5 = mock[(A, B, C, D, E) => Z]
- val g5 = mock[Z => (A, B, C, D, E)]
-
- thabcde.imap5(f5)(g5)
- (ha, hb, hc, hd, he).imap5(f5)(g5)
- }
}
/**