Skip to content

Commit

Permalink
Merge pull request #528 from sellout/shims
Browse files Browse the repository at this point in the history
Port to Cats.
  • Loading branch information
julien-truffaut committed Aug 28, 2017
2 parents 0a2f8a6 + ca1cfdb commit 8344316
Show file tree
Hide file tree
Showing 139 changed files with 466 additions and 1,620 deletions.
26 changes: 0 additions & 26 deletions .travis.yml
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
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
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
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
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:git@github.com: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
@@ -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)
}
}

0 comments on commit 8344316

Please sign in to comment.