Permalink
Browse files

Unambiguous ops (syntax extensions) for scalaz 7. (#1479)

* Unambiguous ops (syntax extensions).

The goal is to allow the user to structure imports so that ambiguous
syntactic extensions are avoided.

The idea is that the import

  import scalaz.syntax.traverse0._

imports syntax for Traverse, but doesn't include syntax for Functor and Foldable.
The usual import

  import scalaz.syntax.traverse._

also brings in the syntax for Functor and Foldable.
There is one change, though: for this import to provide Functor (or Foldable)
syntax, there needs to be a Traverse instance in scope; Functor (or Foldable)
instance will not suffice, even when only Functor (or Foldable) operations
are performed.

This allows us to import

  import scalaz.syntax.monad._
  import scalaz.syntax.traverse0._

and then use both Monad and Traverse syntax extensions without ambiguity.

For some examples, see the diff of SyntaxUsage.scala.

IMPLEMENTATION COMMENTS:

Where previously we had

  trait ToTraverseOps extends ToFunctorOps with ToFoldableOps

we now have (to be refined shortly)

  trait ToTraverseOps0

  trait ToTraverseOps extends ToTraverseOps0 with ToFunctorOps with ToFoldableOps

That is, we provide ToTraverseOps0 which doesn't inherit Functor and Foldable ops.

In order for the inherited ToFunctorOps and ToFoldableOps to actually require
a Traverse instance to work, we pass the required typeclass as a type argument.
Thus we have

  trait ToTraverseOps0[TC[F[_]] <: Traverse[F]]

  trait ToTraverseOps[TC[F[_]] <: Traverse[F]] extends ToTraverseOps0[TC] with ToFunctorOps[TC] with ToFoldableOps[TC]

and then in ToFunctorOps, we require an instance of TC instead of Functor:

  trait ToFunctorOps0[TC[F[_]] <: Functor[F]] {
    implicit def ToFunctorOps[F[_], A](v: F[A])(implicit F0: TC[F]) = ???
  }

There is one more point worth mentioning.
Consider syntax for MonadTell extending syntax for Monad, using this scheme:

  trait ToMonadOps[TC[F[_]] <: Monad[F]]

  trait ToMonadTellOps[TC[F[_], S] <: MonadTell[F, S]] extends ToMonadOps[???]

The kinds of type arguments of ToMonadOps and ToMonadTellOps don't match.
Therefore, we cannot just pass the `TC` type parameter from ToMonadTellOps
to ToMonadOps. The solution is to use an existential

  trait ToMonadTellOps[TC[F[_], S] <: MonadTell[F, S]] extends ToMonadOps[λ[F[_] => TC[F, S] forSome { type S }]]

and, despite many problems with existentials in Scala, the compiler does
consider MonadTell[F, S] forSome { type S } to be a subtype of Monad[F].

* update project/GenTypeClass.scala
  • Loading branch information...
TomasMikula authored and xuwei-k committed Oct 11, 2017
1 parent 645fdf8 commit d6d8f6db89ee67c631e0b6d28e611d9e6ed85b22
Showing with 546 additions and 367 deletions.
  1. +6 −4 core/src/main/scala/scalaz/syntax/AlignSyntax.scala
  2. +52 −95 core/src/main/scala/scalaz/syntax/ApplicativeBuilder.scala
  3. +6 −4 core/src/main/scala/scalaz/syntax/ApplicativePlusSyntax.scala
  4. +9 −7 core/src/main/scala/scalaz/syntax/ApplicativeSyntax.scala
  5. +14 −14 core/src/main/scala/scalaz/syntax/ApplySyntax.scala
  6. +7 −5 core/src/main/scala/scalaz/syntax/ArrowSyntax.scala
  7. +7 −5 core/src/main/scala/scalaz/syntax/AssociativeSyntax.scala
  8. +7 −5 core/src/main/scala/scalaz/syntax/BifoldableSyntax.scala
  9. +7 −5 core/src/main/scala/scalaz/syntax/BifunctorSyntax.scala
  10. +6 −4 core/src/main/scala/scalaz/syntax/BindRecSyntax.scala
  11. +6 −4 core/src/main/scala/scalaz/syntax/BindSyntax.scala
  12. +7 −5 core/src/main/scala/scalaz/syntax/BitraverseSyntax.scala
  13. +6 −4 core/src/main/scala/scalaz/syntax/CatchableSyntax.scala
  14. +7 −5 core/src/main/scala/scalaz/syntax/CategorySyntax.scala
  15. +7 −5 core/src/main/scala/scalaz/syntax/ChoiceSyntax.scala
  16. +6 −4 core/src/main/scala/scalaz/syntax/CobindSyntax.scala
  17. +6 −4 core/src/main/scala/scalaz/syntax/ComonadSyntax.scala
  18. +7 −5 core/src/main/scala/scalaz/syntax/ComposeSyntax.scala
  19. +6 −4 core/src/main/scala/scalaz/syntax/ContravariantSyntax.scala
  20. +6 −4 core/src/main/scala/scalaz/syntax/CozipSyntax.scala
  21. +6 −4 core/src/main/scala/scalaz/syntax/DivideSyntax.scala
  22. +6 −4 core/src/main/scala/scalaz/syntax/DivisibleSyntax.scala
  23. +6 −4 core/src/main/scala/scalaz/syntax/Foldable1Syntax.scala
  24. +6 −4 core/src/main/scala/scalaz/syntax/FoldableSyntax.scala
  25. +8 −6 core/src/main/scala/scalaz/syntax/FunctorSyntax.scala
  26. +6 −4 core/src/main/scala/scalaz/syntax/InvariantFunctorSyntax.scala
  27. +6 −4 core/src/main/scala/scalaz/syntax/IsEmptySyntax.scala
  28. +4 −2 core/src/main/scala/scalaz/syntax/MonadErrorSyntax.scala
  29. +4 −2 core/src/main/scala/scalaz/syntax/MonadListenSyntax.scala
  30. +6 −4 core/src/main/scala/scalaz/syntax/MonadPlusSyntax.scala
  31. +6 −4 core/src/main/scala/scalaz/syntax/MonadSyntax.scala
  32. +4 −2 core/src/main/scala/scalaz/syntax/MonadTellSyntax.scala
  33. +6 −4 core/src/main/scala/scalaz/syntax/NondeterminismSyntax.scala
  34. +6 −4 core/src/main/scala/scalaz/syntax/OptionalSyntax.scala
  35. +6 −4 core/src/main/scala/scalaz/syntax/PlusEmptySyntax.scala
  36. +6 −4 core/src/main/scala/scalaz/syntax/PlusSyntax.scala
  37. +7 −5 core/src/main/scala/scalaz/syntax/ProChoiceSyntax.scala
  38. +7 −5 core/src/main/scala/scalaz/syntax/ProfunctorSyntax.scala
  39. +7 −5 core/src/main/scala/scalaz/syntax/SplitSyntax.scala
  40. +7 −5 core/src/main/scala/scalaz/syntax/StrongSyntax.scala
  41. +87 −47 core/src/main/scala/scalaz/syntax/Syntax.scala
  42. +6 −4 core/src/main/scala/scalaz/syntax/Traverse1Syntax.scala
  43. +6 −4 core/src/main/scala/scalaz/syntax/TraverseSyntax.scala
  44. +8 −6 core/src/main/scala/scalaz/syntax/UnzipSyntax.scala
  45. +6 −4 core/src/main/scala/scalaz/syntax/ZipSyntax.scala
  46. +6 −4 effect/src/main/scala/scalaz/syntax/effect/LiftControlIOSyntax.scala
  47. +6 −4 effect/src/main/scala/scalaz/syntax/effect/LiftIOSyntax.scala
  48. +6 −4 effect/src/main/scala/scalaz/syntax/effect/MonadControlIOSyntax.scala
  49. +6 −4 effect/src/main/scala/scalaz/syntax/effect/MonadIOSyntax.scala
  50. +77 −0 example/src/main/scala/scalaz/example/SyntaxUsage.scala
  51. +26 −13 project/GenTypeClass.scala
  52. +1 −1 tests/src/test/scala/scalaz/FoldableTest.scala
@@ -18,21 +18,23 @@ final class AlignOps[F[_],A] private[syntax](val self: F[A])(implicit val F: Ali
////
}
sealed trait ToAlignOps0 {
implicit def ToAlignOpsUnapply[FA](v: FA)(implicit F0: Unapply[Align, FA]) =
sealed trait ToAlignOpsU[TC[F[_]] <: Align[F]] {
implicit def ToAlignOpsUnapply[FA](v: FA)(implicit F0: Unapply[TC, FA]) =
new AlignOps[F0.M,F0.A](F0(v))(F0.TC)
}
trait ToAlignOps extends ToAlignOps0 with ToFunctorOps {
implicit def ToAlignOps[F[_],A](v: F[A])(implicit F0: Align[F]) =
trait ToAlignOps0[TC[F[_]] <: Align[F]] extends ToAlignOpsU[TC] {
implicit def ToAlignOps[F[_],A](v: F[A])(implicit F0: TC[F]) =
new AlignOps[F,A](v)
////
////
}
trait ToAlignOps[TC[F[_]] <: Align[F]] extends ToAlignOps0[TC] with ToFunctorOps[TC]
trait AlignSyntax[F[_]] extends FunctorSyntax[F] {
implicit def ToAlignOps[A](v: F[A]): AlignOps[F, A] = new AlignOps[F,A](v)(AlignSyntax.this.F)
@@ -2,145 +2,102 @@ package scalaz
package syntax
/** @see [[scalaz.syntax.ApplyOps]]`#|@|` */
private[scalaz] trait ApplicativeBuilder[M[_], A, B] {
val a: M[A]
val b: M[B]
final class ApplicativeBuilder[M[_], A, B](a: M[A], b: M[B])(implicit ap: Apply[M]) {
def apply[C](f: (A, B) => C): M[C] = ap.apply2(a, b)(f)
def apply[C](f: (A, B) => C)(implicit ap: Apply[M]): M[C] = ap.apply2(a, b)(f)
def tupled: M[(A, B)] = apply(Tuple2.apply)
def tupled(implicit ap: Apply[M]): M[(A, B)] = apply(Tuple2.apply)
def ⊛[C](c: M[C]) = new ApplicativeBuilder3[C](c)
def ⊛[C](cc: M[C]) = new ApplicativeBuilder3[C] {
val c = cc
}
def |@|[C](cc: M[C]): ApplicativeBuilder3[C] = ⊛(cc)
sealed abstract class ApplicativeBuilder3[C] {
val c: M[C]
def |@|[C](c: M[C]): ApplicativeBuilder3[C] = ⊛(c)
def apply[D](f: (A, B, C) => D)(implicit ap: Apply[M]): M[D] = ap.apply3(a, b, c)(f)
final class ApplicativeBuilder3[C](c: M[C]) {
def apply[D](f: (A, B, C) => D): M[D] = ap.apply3(a, b, c)(f)
def tupled(implicit ap: Apply[M]): M[(A, B, C)] = apply(Tuple3.apply)
def tupled: M[(A, B, C)] = apply(Tuple3.apply)
def ⊛[D](dd: M[D]) = new ApplicativeBuilder4[D] {
val d = dd
}
def |@|[D](dd: M[D]): ApplicativeBuilder4[D] = ⊛(dd)
def ⊛[D](d: M[D]) = new ApplicativeBuilder4[D](d)
sealed abstract class ApplicativeBuilder4[D] {
val d: M[D]
def |@|[D](d: M[D]): ApplicativeBuilder4[D] = ⊛(d)
def apply[E](f: (A, B, C, D) => E)(implicit ap: Apply[M]): M[E] = ap.apply4(a, b, c, d)(f)
final class ApplicativeBuilder4[D](d: M[D]) {
def apply[E](f: (A, B, C, D) => E): M[E] = ap.apply4(a, b, c, d)(f)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D)] = apply(Tuple4.apply)
def tupled: M[(A, B, C, D)] = apply(Tuple4.apply)
def ⊛[E](ee: M[E]) = new ApplicativeBuilder5[E] {
val e = ee
}
def ⊛[E](e: M[E]) = new ApplicativeBuilder5[E](e)
def |@|[E](ee: M[E]): ApplicativeBuilder5[E] = ⊛(ee)
def |@|[E](e: M[E]): ApplicativeBuilder5[E] = ⊛(e)
sealed abstract class ApplicativeBuilder5[E] {
val e: M[E]
final class ApplicativeBuilder5[E](e: M[E]) {
def apply[F](f: (A, B, C, D, E) => F): M[F] = ap.apply5(a, b, c, d, e)(f)
def apply[F](f: (A, B, C, D, E) => F)(implicit ap: Apply[M]): M[F] = ap.apply5(a, b, c, d, e)(f)
def tupled: M[(A, B, C, D, E)] = apply(Tuple5.apply)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D, E)] = apply(Tuple5.apply)
def ⊛[F](f: M[F]) = new ApplicativeBuilder6[F] {
val ff = f
}
def ⊛[F](f: M[F]) = new ApplicativeBuilder6[F](f)
def |@|[F](f: M[F]): ApplicativeBuilder6[F] = ⊛(f)
sealed abstract class ApplicativeBuilder6[F] {
val ff: M[F]
final class ApplicativeBuilder6[F](ff: M[F]) {
def apply[G](f: (A, B, C, D, E, F) => G): M[G] = ap.apply6(a, b, c, d, e, ff)(f)
def apply[G](f: (A, B, C, D, E, F) => G)(implicit ap: Apply[M]): M[G] = ap.apply6(a, b, c, d, e, ff)(f)
def tupled: M[(A, B, C, D, E, F)] = apply(Tuple6.apply)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D, E, F)] = apply(Tuple6.apply)
def ⊛[G](g: M[G]) = new ApplicativeBuilder7[G](g)
def ⊛[G](gg: M[G]) = new ApplicativeBuilder7[G] {
val g = gg
}
def |@|[G](g: M[G]): ApplicativeBuilder7[G] = ⊛(g)
def |@|[G](gg: M[G]): ApplicativeBuilder7[G] = ⊛(gg)
final class ApplicativeBuilder7[G](g: M[G]) {
def apply[H](f: (A, B, C, D, E, F, G) => H): M[H] = ap.apply7(a, b, c, d, e, ff, g)(f)
sealed abstract class ApplicativeBuilder7[G] {
val g: M[G]
def tupled: M[(A, B, C, D, E, F, G)] = apply(Tuple7.apply)
def apply[H](f: (A, B, C, D, E, F, G) => H)(implicit ap: Apply[M]): M[H] = ap.apply7(a, b, c, d, e, ff, g)(f)
def [H](h: M[H]) = new ApplicativeBuilder8[H](h)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D, E, F, G)] = apply(Tuple7.apply)
def |@|[H](h: M[H]): ApplicativeBuilder8[H] = ⊛(h)
def ⊛[H](hh: M[H]) = new ApplicativeBuilder8[H] {
val h = hh
}
final class ApplicativeBuilder8[H](h: M[H]) {
def apply[I](f: (A, B, C, D, E, F, G, H) => I): M[I] = ap.apply8(a, b, c, d, e, ff, g, h)(f)
def |@|[H](hh: M[H]): ApplicativeBuilder8[H] = ⊛(hh)
def tupled: M[(A, B, C, D, E, F, G, H)] = apply(Tuple8.apply)
sealed abstract class ApplicativeBuilder8[H] {
val h: M[H]
def ⊛[I](i: M[I]) = new ApplicativeBuilder9[I](i)
def apply[I](f: (A, B, C, D, E, F, G, H) => I)(implicit ap: Apply[M]): M[I] = ap.apply8(a, b, c, d, e, ff, g, h)(f)
def |@|[I](i: M[I]): ApplicativeBuilder9[I] = ⊛(i)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D, E, F, G, H)] = apply(Tuple8.apply)
final class ApplicativeBuilder9[I](i: M[I]) {
def apply[J](f: (A, B, C, D, E, F, G, H, I) => J): M[J] = ap.apply9(a, b, c, d, e, ff, g, h, i)(f)
def ⊛[I](ii: M[I]) = new ApplicativeBuilder9[I] {
val i = ii
}
def tupled: M[(A, B, C, D, E, F, G, H, I)] = apply(Tuple9.apply)
def |@|[I](ii: M[I]): ApplicativeBuilder9[I] = ⊛(ii)
def ⊛[J](j: M[J]) = new ApplicativeBuilder10[J](j)
sealed abstract class ApplicativeBuilder9[I] {
val i: M[I]
def |@|[J](j: M[J]): ApplicativeBuilder10[J] = ⊛(j)
def apply[J](f: (A, B, C, D, E, F, G, H, I) => J)(implicit ap: Apply[M]): M[J] = ap.apply9(a, b, c, d, e, ff, g, h, i)(f)
final class ApplicativeBuilder10[J](j: M[J]) {
def apply[K](f: (A, B, C, D, E, F, G, H, I, J) => K): M[K] = ap.apply10(a, b, c, d, e, ff, g, h, i, j)(f)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D, E, F, G, H, I)] = apply(Tuple9.apply)
def tupled: M[(A, B, C, D, E, F, G, H, I, J)] = apply(Tuple10.apply)
def ⊛[J](jj: M[J]) = new ApplicativeBuilder10[J] {
val j = jj
}
def |@|[J](jj: M[J]): ApplicativeBuilder10[J] = ⊛(jj)
sealed abstract class ApplicativeBuilder10[J] {
val j: M[J]
def apply[K](f: (A, B, C, D, E, F, G, H, I, J) => K)(implicit ap: Apply[M]): M[K] = ap.apply10(a, b, c, d, e, ff, g, h, i, j)(f)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D, E, F, G, H, I, J)] = apply(Tuple10.apply)
def ⊛[K](k: M[K]) = new ApplicativeBuilder11[K](k)
def ⊛[K](kk: M[K]) = new ApplicativeBuilder11[K] {
val k = kk
}
def |@|[K](kk: M[K]): ApplicativeBuilder11[K] = ⊛(kk)
sealed abstract class ApplicativeBuilder11[K] {
val k: M[K]
def |@|[K](k: M[K]): ApplicativeBuilder11[K] = ⊛(k)
def apply[L](f: (A, B, C, D, E, F, G, H, I, J, K) => L)(implicit ap: Apply[M]): M[L] =
final class ApplicativeBuilder11[K](k: M[K]) {
def apply[L](f: (A, B, C, D, E, F, G, H, I, J, K) => L): M[L] =
ap.apply11(a, b, c, d, e, ff, g, h, i, j, k)(f)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D, E, F, G, H, I, J, K)] = apply(Tuple11.apply)
def ⊛[L](ll: M[L]) = new ApplicativeBuilder12[L] {
val l = ll
}
def tupled: M[(A, B, C, D, E, F, G, H, I, J, K)] = apply(Tuple11.apply)
def |@|[L](ll: M[L]): ApplicativeBuilder12[L] = ⊛(ll)
def [L](l: M[L]) = new ApplicativeBuilder12[L](l)
sealed abstract class ApplicativeBuilder12[L] {
val l: M[L]
def |@|[L](l: M[L]): ApplicativeBuilder12[L] = ⊛(l)
def apply[MM](f: (A, B, C, D, E, F, G, H, I, J, K, L) => MM)(implicit ap: Apply[M]): M[MM] =
final class ApplicativeBuilder12[L](l: M[L]) {
def apply[MM](f: (A, B, C, D, E, F, G, H, I, J, K, L) => MM): M[MM] =
ap.apply12(a, b, c, d, e, ff, g, h, i, j, k, l)(f)
def tupled(implicit ap: Apply[M]): M[(A, B, C, D, E, F, G, H, I, J, K, L)] = apply(Tuple12.apply)
def tupled: M[(A, B, C, D, E, F, G, H, I, J, K, L)] = apply(Tuple12.apply)
}
}
@@ -8,21 +8,23 @@ final class ApplicativePlusOps[F[_],A] private[syntax](val self: F[A])(implicit
////
}
sealed trait ToApplicativePlusOps0 {
implicit def ToApplicativePlusOpsUnapply[FA](v: FA)(implicit F0: Unapply[ApplicativePlus, FA]) =
sealed trait ToApplicativePlusOpsU[TC[F[_]] <: ApplicativePlus[F]] {
implicit def ToApplicativePlusOpsUnapply[FA](v: FA)(implicit F0: Unapply[TC, FA]) =
new ApplicativePlusOps[F0.M,F0.A](F0(v))(F0.TC)
}
trait ToApplicativePlusOps extends ToApplicativePlusOps0 with ToApplicativeOps with ToPlusEmptyOps {
implicit def ToApplicativePlusOps[F[_],A](v: F[A])(implicit F0: ApplicativePlus[F]) =
trait ToApplicativePlusOps0[TC[F[_]] <: ApplicativePlus[F]] extends ToApplicativePlusOpsU[TC] {
implicit def ToApplicativePlusOps[F[_],A](v: F[A])(implicit F0: TC[F]) =
new ApplicativePlusOps[F,A](v)
////
////
}
trait ToApplicativePlusOps[TC[F[_]] <: ApplicativePlus[F]] extends ToApplicativePlusOps0[TC] with ToApplicativeOps[TC] with ToPlusEmptyOps[TC]
trait ApplicativePlusSyntax[F[_]] extends ApplicativeSyntax[F] with PlusEmptySyntax[F] {
implicit def ToApplicativePlusOps[A](v: F[A]): ApplicativePlusOps[F, A] = new ApplicativePlusOps[F,A](v)(ApplicativePlusSyntax.this.F)
@@ -14,14 +14,14 @@ final class ApplicativeOps[F[_],A] private[syntax](val self: F[A])(implicit val
////
}
sealed trait ToApplicativeOps0 {
implicit def ToApplicativeOpsUnapply[FA](v: FA)(implicit F0: Unapply[Applicative, FA]) =
sealed trait ToApplicativeOpsU[TC[F[_]] <: Applicative[F]] {
implicit def ToApplicativeOpsUnapply[FA](v: FA)(implicit F0: Unapply[TC, FA]) =
new ApplicativeOps[F0.M,F0.A](F0(v))(F0.TC)
}
trait ToApplicativeOps extends ToApplicativeOps0 with ToApplyOps {
implicit def ToApplicativeOps[F[_],A](v: F[A])(implicit F0: Applicative[F]) =
trait ToApplicativeOps0[TC[F[_]] <: Applicative[F]] extends ToApplicativeOpsU[TC] {
implicit def ToApplicativeOps[F[_],A](v: F[A])(implicit F0: TC[F]) =
new ApplicativeOps[F,A](v)
////
@@ -31,12 +31,14 @@ trait ToApplicativeOps extends ToApplicativeOps0 with ToApplyOps {
}
trait ApplicativeIdV[A] extends Ops[A] {
def point[F[_] : Applicative]: F[A] = Applicative[F].point(self)
def pure[F[_] : Applicative]: F[A] = Applicative[F].point(self)
def η[F[_] : Applicative]: F[A] = Applicative[F].point(self)
def point[F[_] : TC]: F[A] = Applicative[F].point(self)
def pure[F[_] : TC]: F[A] = Applicative[F].point(self)
def η[F[_] : TC]: F[A] = Applicative[F].point(self)
} ////
}
trait ToApplicativeOps[TC[F[_]] <: Applicative[F]] extends ToApplicativeOps0[TC] with ToApplyOps[TC]
trait ApplicativeSyntax[F[_]] extends ApplySyntax[F] {
implicit def ToApplicativeOps[A](v: F[A]): ApplicativeOps[F, A] = new ApplicativeOps[F,A](v)(ApplicativeSyntax.this.F)
@@ -30,10 +30,8 @@ final class ApplyOps[F[_],A] private[syntax](val self: F[A])(implicit val F: App
* Warning: each call to `|@|` leads to an allocation of wrapper object. For performance sensitive code, consider using
* [[scalaz.Apply]]`#applyN` directly.
*/
final def |@|[B](fb: F[B]) = new ApplicativeBuilder[F, A, B] {
val a: F[A] = self
val b: F[B] = fb
}
final def |@|[B](fb: F[B]) = new ApplicativeBuilder[F, A, B](self, fb)
/** Alias for `|@|` */
final def ⊛[B](fb: F[B]): ApplicativeBuilder[F, A, B] = |@|(fb)
@@ -46,45 +44,47 @@ final class ApplyOps[F[_],A] private[syntax](val self: F[A])(implicit val F: App
////
}
sealed trait ToApplyOps0 {
implicit def ToApplyOpsUnapply[FA](v: FA)(implicit F0: Unapply[Apply, FA]) =
sealed trait ToApplyOpsU[TC[F[_]] <: Apply[F]] {
implicit def ToApplyOpsUnapply[FA](v: FA)(implicit F0: Unapply[TC, FA]) =
new ApplyOps[F0.M,F0.A](F0(v))(F0.TC)
}
trait ToApplyOps extends ToApplyOps0 with ToFunctorOps {
implicit def ToApplyOps[F[_],A](v: F[A])(implicit F0: Apply[F]) =
trait ToApplyOps0[TC[F[_]] <: Apply[F]] extends ToApplyOpsU[TC] {
implicit def ToApplyOps[F[_],A](v: F[A])(implicit F0: TC[F]) =
new ApplyOps[F,A](v)
////
def ^[F[_],A,B,C](fa: => F[A], fb: => F[B])(
f: (A, B) => C)(implicit F: Apply[F]): F[C] =
f: (A, B) => C)(implicit F: TC[F]): F[C] =
F.apply2(fa, fb)(f)
def ^^[F[_],A,B,C,D](fa: => F[A], fb: => F[B], fc: => F[C])(
f: (A, B, C) => D)(implicit F: Apply[F]): F[D] =
f: (A, B, C) => D)(implicit F: TC[F]): F[D] =
F.apply3(fa, fb, fc)(f)
def ^^^[F[_],A,B,C,D,E](fa: => F[A], fb: => F[B], fc: => F[C], fd: => F[D])(
f: (A,B,C,D) => E)(implicit F: Apply[F]): F[E] =
f: (A,B,C,D) => E)(implicit F: TC[F]): F[E] =
F.apply4(fa, fb, fc, fd)(f)
def ^^^^[F[_],A,B,C,D,E,I](fa: => F[A], fb: => F[B], fc: => F[C], fd: => F[D], fe: => F[E])(
f: (A,B,C,D,E) => I)(implicit F: Apply[F]): F[I] =
f: (A,B,C,D,E) => I)(implicit F: TC[F]): F[I] =
F.apply5(fa, fb, fc, fd, fe)(f)
def ^^^^^[F[_],A,B,C,D,E,I,J](fa: => F[A], fb: => F[B], fc: => F[C], fd: => F[D], fe: => F[E], fi: => F[I])(
f: (A,B,C,D,E,I) => J)(implicit F: Apply[F]): F[J] =
f: (A,B,C,D,E,I) => J)(implicit F: TC[F]): F[J] =
F.apply6(fa, fb, fc, fd, fe, fi)(f)
def ^^^^^^[F[_],A,B,C,D,E,I,J,K](fa: => F[A], fb: => F[B], fc: => F[C], fd: => F[D], fe: => F[E], fi: => F[I], fj: => F[J])(
f: (A,B,C,D,E,I,J) => K)(implicit F: Apply[F]): F[K] =
f: (A,B,C,D,E,I,J) => K)(implicit F: TC[F]): F[K] =
F.apply7(fa, fb, fc, fd, fe, fi, fj)(f)
////
}
trait ToApplyOps[TC[F[_]] <: Apply[F]] extends ToApplyOps0[TC] with ToFunctorOps[TC]
trait ApplySyntax[F[_]] extends FunctorSyntax[F] {
implicit def ToApplyOps[A](v: F[A]): ApplyOps[F, A] = new ApplyOps[F,A](v)(ApplySyntax.this.F)
@@ -16,26 +16,28 @@ final class ArrowOps[F[_, _],A, B] private[syntax](val self: F[A, B])(implicit v
////
}
sealed trait ToArrowOps0 {
implicit def ToArrowOpsUnapply[FA](v: FA)(implicit F0: Unapply2[Arrow, FA]) =
sealed trait ToArrowOpsU[TC[F[_, _]] <: Arrow[F]] {
implicit def ToArrowOpsUnapply[FA](v: FA)(implicit F0: Unapply2[TC, FA]) =
new ArrowOps[F0.M,F0.A,F0.B](F0(v))(F0.TC)
}
trait ToArrowOps extends ToArrowOps0 with ToSplitOps with ToStrongOps with ToCategoryOps {
trait ToArrowOps0[TC[F[_, _]] <: Arrow[F]] extends ToArrowOpsU[TC] {
implicit def ToArrowOps[F[_, _],A, B](v: F[A, B])(implicit F0: Arrow[F]) =
implicit def ToArrowOps[F[_, _],A, B](v: F[A, B])(implicit F0: TC[F]) =
new ArrowOps[F,A, B](v)
implicit def ToArrowVFromKleisliLike[G[_], F[G[_], _, _],A, B](v: F[G, A, B])(implicit F0: Arrow[F[G, ?, ?]]) =
implicit def ToArrowVFromKleisliLike[G[_], F[G[_], _, _],A, B](v: F[G, A, B])(implicit F0: TC[F[G, ?, ?]]) =
new ArrowOps[F[G, ?, ?], A, B](v)(F0)
////
////
}
trait ToArrowOps[TC[F[_, _]] <: Arrow[F]] extends ToArrowOps0[TC] with ToSplitOps[TC] with ToStrongOps[TC] with ToCategoryOps[TC]
trait ArrowSyntax[F[_, _]] extends SplitSyntax[F] with StrongSyntax[F] with CategorySyntax[F] {
implicit def ToArrowOps[A, B](v: F[A, B]): ArrowOps[F, A, B] = new ArrowOps[F, A, B](v)(ArrowSyntax.this.F)
Oops, something went wrong.

0 comments on commit d6d8f6d

Please sign in to comment.