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

Port to Cats. #528

Merged
merged 3 commits into from
Aug 28, 2017
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
26 changes: 0 additions & 26 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ language: scala
scala:
- 2.12.2
- 2.11.8
- 2.10.6
jdk:
- oraclejdk8
notifications:
Expand Down Expand Up @@ -46,28 +45,3 @@ install:
- gem install jekyll -v 3.2.1
after_success:
- '[[ $TRAVIS_BRANCH == "master" && "${TRAVIS_PULL_REQUEST}" == "false" ]] && { sbt +publish ghpagesPushSite; };'
matrix:
include:
- scala: 2.11.8
jdk: oraclejdk8
sudo: required
before_install:
- wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y "deb http://apt.llvm.org/precise/ llvm-toolchain-precise main"
- sudo add-apt-repository -y "deb http://apt.llvm.org/precise/ llvm-toolchain-precise-3.7 main"
- sudo apt-get update -qq
- sudo apt-get install -y libgc-dev clang++-3.7 llvm-3.7 llvm-3.7-dev llvm-3.7-runtime llvm-3.7-tool libunwind7-dev
# Install re2
# https://github.com/scala-native/scala-native/commit/1d312519788534ff41477e4d7f758a6e7451be05#diff-354f30a63fb0907d4ad57269548329e3R28
- sudo apt-get install -y make
- export CXX=clang++-3.7
- git clone https://code.googlesource.com/re2
- pushd re2
- git checkout 2017-03-01
- make -j4 test
- sudo make install prefix=/usr
- make testinstall prefix=/usr
- popd
script:
- sbt ++$TRAVIS_SCALA_VERSION testNative/run
2 changes: 1 addition & 1 deletion bench/src/main/scala/monocle/bench/MonocleLensBench.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import monocle.bench.BenchModel._
import monocle.bench.input.Nested0Input
import org.openjdk.jmh.annotations._

import scalaz.std.option._
import cats.instances.option._

@BenchmarkMode(Array(Mode.AverageTime))
@OutputTimeUnit(TimeUnit.MICROSECONDS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import monocle.bench.input.Nested0Input
import monocle.macros.GenLens
import org.openjdk.jmh.annotations._

import scalaz.std.option._
import cats.instances.option._

@BenchmarkMode(Array(Mode.AverageTime))
@OutputTimeUnit(TimeUnit.MICROSECONDS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import monocle.bench.BenchModel._
import monocle.{PTraversal, Traversal}
import org.openjdk.jmh.annotations.{Benchmark, Scope, State}

import scalaz.std.map._
import cats.instances.map._

@State(Scope.Benchmark)
class MonocleTraversalBench {
Expand All @@ -20,4 +20,4 @@ class MonocleTraversalBench {
@Benchmark def collectionGetAll() = iMapTraversal.getAll(map)
@Benchmark def collectionSet() = iMapTraversal.set(12)(map)
@Benchmark def collectionModify() = iMapTraversal.modify(_ + 1)(map)
}
}
73 changes: 26 additions & 47 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ lazy val Scala211 = "2.11.8"
lazy val buildSettings = Seq(
organization := "com.github.julien-truffaut",
scalaVersion := "2.12.2",
crossScalaVersions := Seq("2.10.6", Scala211, "2.12.2"),
crossScalaVersions := Seq(Scala211, "2.12.2"),
scalacOptions ++= Seq(
"-deprecation",
"-encoding", "UTF-8",
Expand All @@ -24,8 +24,6 @@ lazy val buildSettings = Seq(
"-Ywarn-value-discard",
"-Xfuture"
) ++ (CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 10)) =>
Seq("-Yno-generic-signatures") // no generic signatures for scala 2.10.x, see SI-7932, #571 and #828
case Some((2, n)) if n >= 11 =>
Seq("-Ywarn-unused-import")
case None =>
Expand All @@ -41,17 +39,23 @@ lazy val buildSettings = Seq(
scmInfo := Some(ScmInfo(url("https://github.com/julien-truffaut/Monocle"), "scm:git:[email protected]:julien-truffaut/Monocle.git"))
)

lazy val scalaz = Def.setting("org.scalaz" %%% "scalaz-core" % "7.2.13")
lazy val shapeless = Def.setting("com.chuusai" %%% "shapeless" % "2.3.2")
lazy val catsVersion = "1.0.0-MF"


lazy val cats = Def.setting("org.typelevel" %%% "cats-core" % catsVersion)
lazy val catsFree = Def.setting("org.typelevel" %%% "cats-free" % catsVersion)
lazy val catsLaws = Def.setting("org.typelevel" %%% "cats-laws" % catsVersion)
lazy val newts = Def.setting("com.github.julien-truffaut" %%% "newts-core" % "0.3.0-MF-2")
lazy val scalaz = Def.setting("org.scalaz" %%% "scalaz-core" % "7.2.13")
lazy val shapeless = Def.setting("com.chuusai" %%% "shapeless" % "2.3.2")
lazy val refinedDep = Def.setting("eu.timepit" %%% "refined" % "0.8.2")
lazy val refinedScalacheck = Def.setting("eu.timepit" %%% "refined-scalacheck" % "0.8.2" % "test")

lazy val discipline = Def.setting("org.typelevel" %%% "discipline" % "0.7.3")
lazy val scalacheck = Def.setting("org.scalacheck" %%% "scalacheck" % "1.13.5")
lazy val scalatest = Def.setting("org.scalatest" %%% "scalatest" % "3.0.3" % "test")
lazy val discipline = Def.setting("org.typelevel" %%% "discipline" % "0.7.3")
lazy val scalacheck = Def.setting("org.scalacheck" %%% "scalacheck" % "1.13.5")
lazy val scalatest = Def.setting("org.scalatest" %%% "scalatest" % "3.0.3" % "test")

lazy val macroCompat = Def.setting("org.typelevel" %%% "macro-compat" % "1.1.1")
lazy val macroCompat = Def.setting("org.typelevel" %%% "macro-compat" % "1.1.1")

lazy val macroVersion = "2.1.0"
lazy val paradisePlugin = "org.scalamacros" % "paradise" % macroVersion cross CrossVersion.patch
Expand Down Expand Up @@ -80,15 +84,9 @@ lazy val scalajsSettings = Seq(
"-minSuccessfulTests", "50")
)

lazy val scalanativeSettings = Seq(
scalaVersion := Scala211,
crossScalaVersions := Seq(Scala211)
)

lazy val monocleSettings = buildSettings ++ publishSettings
lazy val monocleJvmSettings = monocleSettings
lazy val monocleJsSettings = monocleSettings ++ scalajsSettings
lazy val monocleNativeSettings = monocleSettings ++ scalanativeSettings

lazy val monocle = project.in(file("."))
.settings(moduleName := "monocle")
Expand All @@ -110,24 +108,16 @@ lazy val monocleJS = project.in(file(".monocleJS"))
.aggregate(coreJS, genericJS, lawJS, macrosJS, stateJS, refinedJS, unsafeJS, testJS)
.dependsOn(coreJS, genericJS, lawJS, macrosJS, stateJS, refinedJS, unsafeJS, testJS % "test-internal -> test")

lazy val monocleNative = project.in(file(".monocleNative"))
.settings(monocleNativeSettings)
.settings(noPublishSettings)
.aggregate(coreNative, stateNative, testNative)
.dependsOn(coreNative, stateNative, testNative)

lazy val coreJVM = core.jvm
lazy val coreJS = core.js
lazy val coreNative = core.native
lazy val core = crossProject(JVMPlatform, JSPlatform, NativePlatform)
lazy val core = crossProject(JVMPlatform, JSPlatform)
.settings(moduleName := "monocle-core")
.configureCross(
_.jvmSettings(monocleJvmSettings),
_.jsSettings(monocleJsSettings),
_.nativeSettings(monocleNativeSettings)
_.jsSettings(monocleJsSettings)
)
.jvmSettings(mimaSettings("core"): _*)
.settings(libraryDependencies += scalaz.value)
.settings(libraryDependencies ++= Seq(cats.value, catsFree.value, newts.value))
.jvmSettings(
libraryDependencies ++= PartialFunction.condOpt(CrossVersion.partialVersion(scalaVersion.value)) {
case Some((2, 11)) => "org.scala-lang.modules" %% "scala-java8-compat" % "0.7.0"
Expand All @@ -143,7 +133,7 @@ lazy val generic = crossProject(JVMPlatform, JSPlatform).dependsOn(core)
_.jsSettings(monocleJsSettings)
)
.jvmSettings(mimaSettings("generic"): _*)
.settings(libraryDependencies ++= Seq(scalaz.value, shapeless.value))
.settings(libraryDependencies ++= Seq(cats.value, shapeless.value))

lazy val refinedJVM = refined.jvm
lazy val refinedJS = refined.js
Expand All @@ -153,7 +143,7 @@ lazy val refined = crossProject(JVMPlatform, JSPlatform).dependsOn(core)
_.jvmSettings(monocleJvmSettings),
_.jsSettings(monocleJsSettings)
)
.settings(libraryDependencies ++= Seq(scalaz.value, refinedDep.value))
.settings(libraryDependencies ++= Seq(cats.value, refinedDep.value))

lazy val lawJVM = law.jvm
lazy val lawJS = law.js
Expand Down Expand Up @@ -190,15 +180,13 @@ lazy val macros = crossProject(JVMPlatform, JSPlatform).dependsOn(core)

lazy val stateJVM = state.jvm
lazy val stateJS = state.js
lazy val stateNative = state.native
lazy val state = crossProject(JVMPlatform, JSPlatform, NativePlatform).dependsOn(core)
lazy val state = crossProject(JVMPlatform, JSPlatform).dependsOn(core)
.settings(moduleName := "monocle-state")
.configureCross(
_.jvmSettings(monocleJvmSettings),
_.jsSettings(monocleJsSettings),
_.nativeSettings(monocleNativeSettings)
_.jsSettings(monocleJsSettings)
)
.settings(libraryDependencies ++= Seq(scalaz.value))
.settings(libraryDependencies ++= Seq(cats.value))

lazy val unsafeJVM = unsafe.jvm
lazy val unsafeJS = unsafe.js
Expand All @@ -209,7 +197,7 @@ lazy val unsafe = crossProject(JVMPlatform, JSPlatform).dependsOn(core)
_.jsSettings(monocleJsSettings)
)
.jvmSettings(mimaSettings("unsafe"): _*)
.settings(libraryDependencies ++= Seq(scalaz.value, shapeless.value))
.settings(libraryDependencies ++= Seq(cats.value, shapeless.value))

lazy val testJVM = test.jvm
lazy val testJS = test.js
Expand All @@ -221,22 +209,15 @@ lazy val test = crossProject(JVMPlatform, JSPlatform).dependsOn(core, generic
)
.settings(noPublishSettings: _*)
.settings(
libraryDependencies ++= Seq(scalaz.value, shapeless.value, scalatest.value, refinedScalacheck.value, compilerPlugin(paradisePlugin))
)
lazy val testNative = project.in(file("testNative")).dependsOn(coreNative, stateNative)
.settings(moduleName := "monocle-test-native")
.settings(monocleNativeSettings)
.settings(noPublishSettings)
.settings(
libraryDependencies ++= Seq(scalaz.value)
libraryDependencies ++= Seq(cats.value, catsLaws.value, shapeless.value, scalatest.value, refinedScalacheck.value, compilerPlugin(paradisePlugin))
)
.enablePlugins(ScalaNativePlugin)

lazy val bench = project.dependsOn(coreJVM, genericJVM, macrosJVM)
.settings(moduleName := "monocle-bench")
.settings(monocleJvmSettings)
.settings(noPublishSettings)
.settings(libraryDependencies ++= Seq(
scalaz.value,
shapeless.value,
compilerPlugin(paradisePlugin)
)).enablePlugins(JmhPlugin)
Expand All @@ -246,7 +227,7 @@ lazy val example = project.dependsOn(coreJVM, genericJVM, refinedJVM, macrosJVM,
.settings(monocleJvmSettings)
.settings(noPublishSettings)
.settings(
libraryDependencies ++= Seq(scalaz.value, shapeless.value, scalatest.value, compilerPlugin(paradisePlugin))
libraryDependencies ++= Seq(cats.value, shapeless.value, scalatest.value, compilerPlugin(paradisePlugin))
)

lazy val docs = project.dependsOn(coreJVM, unsafeJVM, macrosJVM, example)
Expand All @@ -259,7 +240,7 @@ lazy val docs = project.dependsOn(coreJVM, unsafeJVM, macrosJVM, example)
.settings(docSettings)
.settings(tutScalacOptions ~= (_.filterNot(Set("-Ywarn-unused-import", "-Ywarn-dead-code"))))
.settings(
libraryDependencies ++= Seq(scalaz.value, shapeless.value, compilerPlugin(paradisePlugin))
libraryDependencies ++= Seq(cats.value, shapeless.value, compilerPlugin(paradisePlugin))
)

lazy val docsMappingsAPIDir = settingKey[String]("Name of subdirectory in site target directory for api docs")
Expand Down Expand Up @@ -346,13 +327,11 @@ lazy val publishSettings = Seq(
inquireVersions,
runTest,
releaseStepCommand(s"++$Scala211"),
releaseStepCommand("testNative/run"),
setReleaseVersion,
commitReleaseVersion,
tagRelease,
publishArtifacts,
releaseStepCommand(s"++$Scala211"),
releaseStepCommand("monocleNative/publishSigned"),
setNextVersion,
commitNextVersion,
pushChanges
Expand Down
36 changes: 15 additions & 21 deletions core/shared/src/main/scala/monocle/Fold.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package monocle

import monocle.function.fields.{first, second}
import scalaz.std.anyVal._
import scalaz.std.list._
import scalaz.std.option._
import scalaz.syntax.std.boolean._
import scalaz.syntax.std.option._
import scalaz.syntax.tag._
import scalaz.{Choice, Foldable, Monoid, Unzip, \/}
import cats.{Foldable, Monoid}
import cats.arrow.Choice
import cats.instances.int._
import cats.instances.list._
import cats.syntax.either._
import newts.syntax.all._
import scala.{Either => \/}

/**
* A [[Fold]] can be seen as a [[Getter]] with many targets or
Expand Down Expand Up @@ -38,31 +37,31 @@ abstract class Fold[S, A] extends Serializable { self =>

/** find the first target matching the predicate */
@inline final def find(p: A => Boolean): S => Option[A] =
foldMap(a => (if(p(a)) Some(a) else None).first)(_).unwrap
foldMap(a => (if(p(a)) Some(a) else None).asFirstOption)(_).unwrap

/** get the first target */
@inline final def headOption(s: S): Option[A] =
foldMap(Option(_).first)(s).unwrap
foldMap(Option(_).asFirstOption)(s).unwrap

/** get the last target */
@inline final def lastOption(s: S): Option[A] =
foldMap(Option(_).last)(s).unwrap
foldMap(Option(_).asLastOption)(s).unwrap

/** check if at least one target satisfies the predicate */
@inline final def exist(p: A => Boolean): S => Boolean =
foldMap(p(_).disjunction)(_).unwrap
foldMap(p(_).asAny)(_).unwrap

/** check if all targets satisfy the predicate */
@inline final def all(p: A => Boolean): S => Boolean =
foldMap(p(_).conjunction)(_).unwrap
foldMap(p(_).asAll)(_).unwrap

/** calculate the number of targets */
@inline final def length(s: S): Int =
foldMap(_ => 1)(s)

/** check if there is no target */
@inline final def isEmpty(s: S): Boolean =
foldMap(_ => false.conjunction)(s).unwrap
foldMap(_ => false.asAll)(s).unwrap

/** check if there is at least one target */
@inline final def nonEmpty(s: S): Boolean =
Expand Down Expand Up @@ -161,7 +160,7 @@ object Fold extends FoldInstances {
def select[A](p: A => Boolean): Fold[A, A] =
new Fold[A, A] {
def foldMap[M: Monoid](f: A => M)(s: A): M =
if (p(s)) f(s) else Monoid[M].zero
if (p(s)) f(s) else Monoid[M].empty
}

/** [[Fold]] that points to nothing */
Expand All @@ -178,7 +177,7 @@ object Fold extends FoldInstances {

sealed abstract class FoldInstances {
implicit val foldChoice: Choice[Fold] = new Choice[Fold]{
def choice[A, B, C](f: => Fold[A, C], g: => Fold[B, C]): Fold[A \/ B, C] =
def choice[A, B, C](f: Fold[A, C], g: Fold[B, C]): Fold[A \/ B, C] =
f choice g

def id[A]: Fold[A, A] =
Expand All @@ -187,9 +186,4 @@ sealed abstract class FoldInstances {
def compose[A, B, C](f: Fold[B, C], g: Fold[A, B]): Fold[A, C] =
g composeFold f
}

implicit def foldUnzip[S]: Unzip[Fold[S, ?]] = new Unzip[Fold[S, ?]] {
override def unzip[A, B](f: Fold[S, (A, B)]): (Fold[S, A], Fold[S, B]) =
(f composeLens first, f composeLens second)
}
}
Loading