From 355979eea4297fdca34c8c784299ed72264ab9f6 Mon Sep 17 00:00:00 2001 From: drdozer Date: Thu, 28 Mar 2019 23:33:46 +0000 Subject: [PATCH 1/3] Removed Ops and replaced them with forwarders. --- core/src/main/scala/cats/syntax/eq.scala | 6 ++---- core/src/main/scala/cats/syntax/group.scala | 8 +++----- core/src/main/scala/cats/syntax/order.scala | 9 ++++----- .../main/scala/cats/syntax/partialOrder.scala | 18 ++++++++---------- .../src/main/scala/cats/syntax/semigroup.scala | 8 +++----- 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/core/src/main/scala/cats/syntax/eq.scala b/core/src/main/scala/cats/syntax/eq.scala index 87250f8643..ce1ec8d629 100644 --- a/core/src/main/scala/cats/syntax/eq.scala +++ b/core/src/main/scala/cats/syntax/eq.scala @@ -1,14 +1,12 @@ package cats package syntax -import cats.macros.Ops - trait EqSyntax { implicit def catsSyntaxEq[A: Eq](a: A): EqOps[A] = new EqOps[A](a) } final class EqOps[A: Eq](lhs: A) { - def ===(rhs: A): Boolean = macro Ops.binop[A, Boolean] - def =!=(rhs: A): Boolean = macro Ops.binop[A, Boolean] + def ===(rhs: A): Boolean = implicitly[Eq[A]].eqv(lhs, rhs) + def =!=(rhs: A): Boolean = implicitly[Eq[A]].neqv(lhs, rhs) } diff --git a/core/src/main/scala/cats/syntax/group.scala b/core/src/main/scala/cats/syntax/group.scala index dca6c12780..d5584b4f12 100644 --- a/core/src/main/scala/cats/syntax/group.scala +++ b/core/src/main/scala/cats/syntax/group.scala @@ -1,8 +1,6 @@ package cats package syntax -import cats.macros.Ops - trait GroupSyntax extends SemigroupSyntax { // TODO: use simulacrum instances eventually implicit def catsSyntaxGroup[A: Group](a: A): GroupOps[A] = @@ -10,7 +8,7 @@ trait GroupSyntax extends SemigroupSyntax { } final class GroupOps[A: Group](lhs: A) { - def |-|(rhs: A): A = macro Ops.binop[A, A] - def remove(rhs: A): A = macro Ops.binop[A, A] - def inverse(): A = macro Ops.unop[A] + def |-|(rhs: A): A = implicitly[Group[A]].remove(lhs, rhs) + def remove(rhs: A): A = implicitly[Group[A]].remove(lhs, rhs) + def inverse(): A = implicitly[Group[A]].inverse(lhs) } diff --git a/core/src/main/scala/cats/syntax/order.scala b/core/src/main/scala/cats/syntax/order.scala index e5c14bfe4d..19dc18d2d7 100644 --- a/core/src/main/scala/cats/syntax/order.scala +++ b/core/src/main/scala/cats/syntax/order.scala @@ -1,7 +1,6 @@ package cats package syntax -import cats.macros.Ops import cats.kernel.Comparison trait OrderSyntax extends PartialOrderSyntax { @@ -10,8 +9,8 @@ trait OrderSyntax extends PartialOrderSyntax { } final class OrderOps[A: Order](lhs: A) { - def compare(rhs: A): Int = macro Ops.binop[A, Int] - def min(rhs: A): A = macro Ops.binop[A, A] - def max(rhs: A): A = macro Ops.binop[A, A] - def comparison(rhs: A): Comparison = macro Ops.binop[A, Comparison] + def compare(rhs: A): Int = implicitly[Order[A]].compare(lhs, rhs) + def min(rhs: A): A = implicitly[Order[A]].min(lhs, rhs) + def max(rhs: A): A = implicitly[Order[A]].max(lhs, rhs) + def comparison(rhs: A): Comparison = implicitly[Order[A]].comparison(lhs, rhs) } diff --git a/core/src/main/scala/cats/syntax/partialOrder.scala b/core/src/main/scala/cats/syntax/partialOrder.scala index 21b350f732..7208f543bf 100644 --- a/core/src/main/scala/cats/syntax/partialOrder.scala +++ b/core/src/main/scala/cats/syntax/partialOrder.scala @@ -1,21 +1,19 @@ package cats package syntax -import cats.macros.Ops - trait PartialOrderSyntax extends EqSyntax { implicit def catsSyntaxPartialOrder[A: PartialOrder](a: A): PartialOrderOps[A] = new PartialOrderOps[A](a) } final class PartialOrderOps[A](lhs: A)(implicit A: PartialOrder[A]) { - def >(rhs: A): Boolean = macro Ops.binop[A, Boolean] - def >=(rhs: A): Boolean = macro Ops.binop[A, Boolean] - def <(rhs: A): Boolean = macro Ops.binop[A, Boolean] - def <=(rhs: A): Boolean = macro Ops.binop[A, Boolean] + def >(rhs: A): Boolean = A.gt(lhs, rhs) + def >=(rhs: A): Boolean = A.gteqv(lhs, rhs) + def <(rhs: A): Boolean = A.lt(lhs, rhs) + def <=(rhs: A): Boolean = A.lteqv(lhs, rhs) - def partialCompare(rhs: A): Double = macro Ops.binop[A, Double] - def tryCompare(rhs: A): Option[Int] = macro Ops.binop[A, Option[Int]] - def pmin(rhs: A): Option[A] = macro Ops.binop[A, Option[A]] - def pmax(rhs: A): Option[A] = macro Ops.binop[A, Option[A]] + def partialCompare(rhs: A): Double = A.partialCompare(lhs, rhs) + def tryCompare(rhs: A): Option[Int] = A.tryCompare(lhs, rhs) + def pmin(rhs: A): Option[A] = A.pmin(lhs, rhs) + def pmax(rhs: A): Option[A] = A.pmax(lhs, rhs) } diff --git a/core/src/main/scala/cats/syntax/semigroup.scala b/core/src/main/scala/cats/syntax/semigroup.scala index b87cfce3ba..5360340882 100644 --- a/core/src/main/scala/cats/syntax/semigroup.scala +++ b/core/src/main/scala/cats/syntax/semigroup.scala @@ -1,8 +1,6 @@ package cats package syntax -import cats.macros.Ops - trait SemigroupSyntax { // TODO: use simulacrum instances eventually implicit def catsSyntaxSemigroup[A: Semigroup](a: A): SemigroupOps[A] = @@ -10,7 +8,7 @@ trait SemigroupSyntax { } final class SemigroupOps[A: Semigroup](lhs: A) { - def |+|(rhs: A): A = macro Ops.binop[A, A] - def combine(rhs: A): A = macro Ops.binop[A, A] - def combineN(rhs: Int): A = macro Ops.binop[A, A] + def |+|(rhs: A): A = implicitly[Semigroup[A]].combine(lhs, rhs) + def combine(rhs: A): A = implicitly[Semigroup[A]].combine(lhs, rhs) + def combineN(rhs: Int): A = implicitly[Semigroup[A]].combineN(lhs, rhs) } From 2d4cc2c74fad0c00705461479671c83ce9002df4 Mon Sep 17 00:00:00 2001 From: drdozer Date: Fri, 29 Mar 2019 14:14:26 +0000 Subject: [PATCH 2/3] Updated FunctionK.lift as per https://github.com/typelevel/cats/issues/2553#issuecomment-443416009 --- .../src/main/scala/cats/arrow/FunctionK.scala | 71 ++----------------- 1 file changed, 5 insertions(+), 66 deletions(-) diff --git a/core/src/main/scala/cats/arrow/FunctionK.scala b/core/src/main/scala/cats/arrow/FunctionK.scala index a9987ef79f..f947d9b39d 100644 --- a/core/src/main/scala/cats/arrow/FunctionK.scala +++ b/core/src/main/scala/cats/arrow/FunctionK.scala @@ -3,8 +3,6 @@ package arrow import cats.data.Coproduct -import cats.macros.MacroCompat - /** * `FunctionK[F[_], G[_]]` is a functor transformation from `F` to `G` * in the same manner that function `A => B` is a morphism from values @@ -80,73 +78,14 @@ object FunctionK { * * Additionally, the type parameters on `f` must not be specified. */ - def lift[F[_], G[_]](f: (F[α] ⇒ G[α]) forSome { type α }): FunctionK[F, G] = - macro FunctionKMacros.lift[F, G] - -} - -private[arrow] object FunctionKMacros extends MacroCompat { - - def lift[F[_], G[_]](c: Context)( - f: c.Expr[(F[α] ⇒ G[α]) forSome { type α }] - )( - implicit evF: c.WeakTypeTag[F[_]], evG: c.WeakTypeTag[G[_]] - ): c.Expr[FunctionK[F, G]] = - c.Expr[FunctionK[F, G]](new Lifter[c.type ](c).lift[F, G](f.tree)) - // ^^note: extra space after c.type to appease scalastyle - - private[this] class Lifter[C <: Context](val c: C) { - import c.universe._ - - def lift[F[_], G[_]](tree: Tree)( - implicit evF: c.WeakTypeTag[F[_]], evG: c.WeakTypeTag[G[_]] - ): Tree = unblock(tree) match { - case q"($param) => $trans[..$typeArgs](${ arg: Ident })" if param.name == arg.name ⇒ + def lift[F[_]]: LiftPartiallyApplied[F] = new LiftPartiallyApplied - typeArgs - .collect { case tt: TypeTree => tt } - .find(tt => Option(tt.original).isDefined) - .foreach { param => c.abort(param.pos, - s"type parameter $param must not be supplied when lifting function $trans to FunctionK") - } + private[arrow] final class LiftPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + type T - val F = punchHole(evF.tpe) - val G = punchHole(evG.tpe) - - q""" - new FunctionK[$F, $G] { - def apply[A](fa: $F[A]): $G[A] = $trans(fa) - } - """ - case other ⇒ - c.abort(other.pos, s"Unexpected tree $other when lifting to FunctionK") - } - - private[this] def unblock(tree: Tree): Tree = tree match { - case Block(Nil, expr) ⇒ expr - case _ ⇒ tree + def apply[G[_]](f: F[T] => G[T]): FunctionK[F, G] = new FunctionK[F, G] { + def apply[A](fa: F[A]): G[A] = f(fa.asInstanceOf[F[T]]).asInstanceOf[G[A]] } - - private[this] def punchHole(tpe: Type): Tree = tpe match { - case PolyType(undet :: Nil, underlying: TypeRef) ⇒ - val α = compatNewTypeName(c, "α") - def rebind(typeRef: TypeRef): Tree = - if (typeRef.sym == undet) tq"$α" - else { - val args = typeRef.args.map { - case ref: TypeRef => rebind(ref) - case arg => tq"$arg" - } - tq"${typeRef.sym}[..$args]" - } - val rebound = rebind(underlying) - tq"""({type λ[$α] = $rebound})#λ""" - case TypeRef(pre, sym, Nil) ⇒ - tq"$sym" - case _ => - c.abort(c.enclosingPosition, s"Unexpected type $tpe when lifting to FunctionK") - } - } } From f0e8cf3e224d215e8162fcf918323f68fbc73324 Mon Sep 17 00:00:00 2001 From: drdozer Date: Fri, 29 Mar 2019 15:30:28 +0000 Subject: [PATCH 3/3] Fixed commit conflict. --- core/src/main/scala/cats/arrow/FunctionK.scala | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/src/main/scala/cats/arrow/FunctionK.scala b/core/src/main/scala/cats/arrow/FunctionK.scala index f658bf1f69..413f72a501 100644 --- a/core/src/main/scala/cats/arrow/FunctionK.scala +++ b/core/src/main/scala/cats/arrow/FunctionK.scala @@ -3,11 +3,8 @@ package arrow import scala.reflect.macros.blackbox.Context -<<<<<<< HEAD -======= import cats.data.{EitherK, Tuple2K} ->>>>>>> 60c2fe6336f1e4dff1cd7d7eb839c19f83778b63 /** * `FunctionK[F[_], G[_]]` is a functor transformation from `F` to `G` * in the same manner that function `A => B` is a morphism from values