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

Deprecate CartesianBuilder, finish up #1487 #1745

Merged
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
3 changes: 0 additions & 3 deletions .jvmopts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
# see https://weblogs.java.net/blog/kcpeppe/archive/2013/12/11/case-study-jvm-hotspot-flags
-Dfile.encoding=UTF8
-Xms1G
-Xmx6G
-XX:MaxPermSize=512M
-XX:ReservedCodeCacheSize=250M
-XX:+TieredCompilation
-XX:-UseGCOverheadLimit
# effectively adds GC to Perm space
-XX:+CMSClassUnloadingEnabled
# must be enabled for CMSClassUnloadingEnabled to work
Copy link
Contributor Author

@kailuowang kailuowang Jun 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DavidGregory084 pointed out that these comments causes problem on Windows.

-XX:+UseConcMarkSweepGC
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

old one is deprecated.

// 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
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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))))
* }}}
*/
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/data/OneAnd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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))))
}


Expand Down
5 changes: 2 additions & 3 deletions core/src/main/scala/cats/data/Tuple2K.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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, α]]]
Expand Down
1 change: 0 additions & 1 deletion core/src/main/scala/cats/syntax/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ trait AllSyntax
with TraverseFilterSyntax
with TraverseSyntax
with NonEmptyTraverseSyntax
with TupleSyntax
with ValidatedSyntax
with VectorSyntax
with WriterSyntax
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/syntax/apply.scala
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/scala/cats/syntax/cartesian.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 0 additions & 1 deletion core/src/main/scala/cats/syntax/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions core/src/main/scala/cats/syntax/tuple.scala

This file was deleted.

4 changes: 2 additions & 2 deletions docs/src/main/tut/datatypes/freeapplicative.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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?
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/tut/datatypes/validated.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
1 change: 0 additions & 1 deletion docs/src/main/tut/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ All other symbols can be imported with `import cats.implicits._`

| Symbol | Name | Nickname | Type Class | Signature |
| -------------------------------- | ---------------------- | ---------------- | ----------------------- | --------------------------------------------------------- |
| <code>fa &#124;@&#124; fb</code> | Cartesian builder | Cinnabon, scream | `Cartesian[F[_]]` | <code>&#124;@&#124;(fa: F[A])(fb: F[B]): F[(A, B)]</code> |
| `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` |
Expand Down
6 changes: 3 additions & 3 deletions docs/src/main/tut/typeclasses/applicative.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions docs/src/main/tut/typeclasses/invariantmonoidal.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
)
```

Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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))
)
```

Expand Down
2 changes: 1 addition & 1 deletion free/src/test/scala/cats/free/FreeApplicativeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
19 changes: 14 additions & 5 deletions project/Boilerplate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
|
Expand Down Expand Up @@ -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
Expand All @@ -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)
-}
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}

Expand Down Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
}

Expand Down
75 changes: 26 additions & 49 deletions tests/src/test/scala/cats/tests/SyntaxTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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)
}
}

/**
Expand Down