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

Replace machinist macros by plain forwarders #2925

Merged
merged 1 commit into from
Jul 1, 2019
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
6 changes: 4 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,15 @@ def macroDependencies(scalaVersion: String) =
lazy val catsSettings = Seq(
incOptions := incOptions.value.withLogRecompileOnMacro(false),
libraryDependencies ++= Seq(
"org.typelevel" %%% "machinist" % "0.6.8",
compilerPlugin("org.typelevel" %% "kind-projector" % kindProjectorVersion)
) ++ macroDependencies(scalaVersion.value)
) ++ commonSettings ++ publishSettings ++ scoverageSettings ++ simulacrumSettings

lazy val simulacrumSettings = Seq(
libraryDependencies += "com.github.mpilquist" %%% "simulacrum" % "0.19.0" % Provided,
libraryDependencies ++= Seq(
scalaOrganization.value % "scala-reflect" % scalaVersion.value % Provided,
"com.github.mpilquist" %%% "simulacrum" % "0.19.0" % Provided
),
pomPostProcess := { (node: xml.Node) =>
new RuleTransformer(new RewriteRule {
override def transform(node: xml.Node): Seq[xml.Node] = node match {
Expand Down
6 changes: 2 additions & 4 deletions core/src/main/scala/cats/syntax/eq.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cats
package syntax

import cats.macros.Ops

trait EqSyntax {

/** not final so it can be disabled in favor of scalactic equality in tests */
Expand All @@ -11,8 +9,8 @@ trait EqSyntax {
}

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 = Eq[A].eqv(lhs, rhs)
def =!=(rhs: A): Boolean = Eq[A].neqv(lhs, rhs)
def eqv(rhs: A): Boolean = Eq[A].eqv(lhs, rhs)
def neqv(rhs: A): Boolean = Eq[A].neqv(lhs, rhs)
}
8 changes: 3 additions & 5 deletions core/src/main/scala/cats/syntax/group.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package cats
package syntax

import cats.macros.Ops

trait GroupSyntax extends SemigroupSyntax {
// TODO: use simulacrum instances eventually
implicit final def catsSyntaxGroup[A: Group](a: A): GroupOps[A] =
new GroupOps[A](a)
}

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 = Group[A].remove(lhs, rhs)
def remove(rhs: A): A = Group[A].remove(lhs, rhs)
def inverse(): A = Group[A].inverse(lhs)
}
4 changes: 1 addition & 3 deletions core/src/main/scala/cats/syntax/hash.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package cats
package syntax

import cats.macros.Ops

trait HashSyntax {

implicit def catsSyntaxHash[A: Hash](a: A): HashOps[A] =
Expand All @@ -15,5 +13,5 @@ final class HashOps[A: Hash](a: A) {
/**
* Gets the hash code of this object given an implicit `Hash` instance.
*/
def hash: Int = macro Ops.unop0[Int]
def hash: Int = Hash[A].hash(a)
}
9 changes: 4 additions & 5 deletions core/src/main/scala/cats/syntax/order.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cats
package syntax

import cats.macros.Ops
import cats.kernel.Comparison

trait OrderSyntax extends PartialOrderSyntax {
Expand All @@ -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 = Order[A].compare(lhs, rhs)
def min(rhs: A): A = Order[A].min(lhs, rhs)
def max(rhs: A): A = Order[A].max(lhs, rhs)
def comparison(rhs: A): Comparison = Order[A].comparison(lhs, rhs)
}
18 changes: 8 additions & 10 deletions core/src/main/scala/cats/syntax/partialOrder.scala
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package cats
package syntax

import cats.macros.Ops

trait PartialOrderSyntax extends EqSyntax {
implicit final 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)
}
8 changes: 3 additions & 5 deletions core/src/main/scala/cats/syntax/semigroup.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package cats
package syntax

import cats.macros.Ops

trait SemigroupSyntax {
// TODO: use simulacrum instances eventually
implicit final def catsSyntaxSemigroup[A: Semigroup](a: A): SemigroupOps[A] =
new SemigroupOps[A](a)
}

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 = Semigroup[A].combine(lhs, rhs)
def combine(rhs: A): A = Semigroup[A].combine(lhs, rhs)
def combineN(rhs: Int): A = Semigroup[A].combineN(lhs, rhs)
}
7 changes: 0 additions & 7 deletions docs/src/main/tut/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ position: 40
* [Where is `IO`/`Task`?](#task)
* [What does `@typeclass` mean?](#simulacrum)
* [What do types like `?` and `λ` mean?](#kind-projector)
* [What does `macro Ops` do? What is `cats.macros.Ops`?](#machinist)
* [What is `tailRecM`?](#tailrecm)
* [What does this symbol mean?](#symbol)
* [How can I test instances against their type classes' laws?](#law-testing)
Expand Down Expand Up @@ -155,12 +154,6 @@ Cats defines a wealth of type classes and type class instances. For a number of

**Enter [kind-projector](https://github.com/non/kind-projector)!** kind-projector is a compiler plugin which provides a convenient syntax for dealing with type lambdas. The symbols `?` and `λ` are treated specially by kind-projector, and expanded into the more verbose definitions that would be required were it not to be used. You can read more about kind-projector at the [project page](https://github.com/non/kind-projector).

## <a id="machinist" href="#machinist"></a>What does `macro Ops` do? What is `cats.macros.Ops`?

`macro Ops` invokes the [Machinist](https://github.com/typelevel/machinist) Ops macro, and is used in Cats in a number of places to enrich types with operations with the minimal possible cost when those operations are called in code. Machinist supports an extension mechanism where users of the macro can provide a mapping between symbolic operator names and method names. The `cats.macros.Ops` class uses this extension mechanism to supply the set of mappings that the Cats project is interested in.

More about the history of machinist and how it works can be discovered at the [project page](https://github.com/typelevel/machinist), or [this article on the typelevel blog](http://typelevel.org/blog/2013/10/13/spires-ops-macros.html).

## <a id="tailrecm" href="#tailrecm"></a>What is `tailRecM`?

The `FlatMap` type class has a `tailRecM` method with the following signature:
Expand Down
22 changes: 0 additions & 22 deletions macros/src/main/scala/cats/macros/Ops.scala

This file was deleted.