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

Apply syntax for tuples #1487

Closed
Closed
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
-XX:+UseConcMarkSweepGC
Copy link
Member Author

@DavidGregory084 DavidGregory084 May 20, 2017

Choose a reason for hiding this comment

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

Comments in here cause Could not find or load main class: # when starting sbt on Windows

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.Invalid(NonEmptyList.of("error 1"))
* scala> val v2: Validated[NonEmptyList[Error], Int] = Validated.Invalid(NonEmptyList.of("error 2"))
* scala> val eithert: EitherT[Option, Error, Int] = EitherT(Some(Either.left("error 3")))
* scala> eithert.withValidated { v3 => (v1 |@| v2 |@| v3.leftMap(NonEmptyList.of(_))).map{ case (i, j, k) => i + j + k } }
* scala> eithert.withValidated { v3 => (v1, v2, v3.leftMap(NonEmptyList.of(_))).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
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 @@ -42,7 +42,6 @@ trait AllSyntax
with StrongSyntax
with TraverseFilterSyntax
with TraverseSyntax
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
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 @@ -42,7 +42,6 @@ package object syntax {
object monadTrans extends MonadTransSyntax
object traverse extends TraverseSyntax
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.

2 changes: 1 addition & 1 deletion docs/src/main/tut/typeclasses/applicative.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ The second expects the effects in a tuple and works by enriching syntax on top o
`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
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
18 changes: 13 additions & 5 deletions project/Boilerplate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -238,15 +238,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 +261,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
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 @@ -180,28 +180,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 @@ -274,38 +283,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