Permalink
Browse files

Add cats interop module

  • Loading branch information...
alexarchambault committed Oct 9, 2018
1 parent 0fdccbe commit 3101909b6d6b5d40f3a4e9a9bf8edb43a004c177
@@ -117,6 +117,20 @@ lazy val scalaz = crossProject("interop", "scalaz")(JSPlatform, JVMPlatform)
lazy val scalazJvm = scalaz.jvm lazy val scalazJvm = scalaz.jvm
lazy val scalazJs = scalaz.js lazy val scalazJs = scalaz.js
lazy val cats = crossProject("interop", "cats")(JSPlatform, JVMPlatform)
.dependsOn(cache, tests % "test->test")
.settings(
name := "cats-interop",
shared,
utest,
Mima.previousArtifacts,
coursierPrefix,
libs += CrossDeps.catsEffect.value
)
lazy val catsJvm = cats.jvm
lazy val catsJs = cats.js
lazy val bootstrap = project("bootstrap") lazy val bootstrap = project("bootstrap")
.settings( .settings(
pureJava, pureJava,
@@ -258,6 +272,7 @@ lazy val jvm = project("jvm")
paths, paths,
cacheJvm, cacheJvm,
scalazJvm, scalazJvm,
catsJvm,
bootstrap, bootstrap,
extra, extra,
cli, cli,
@@ -288,6 +303,8 @@ lazy val js = project("js")
lazy val coursier = project("coursier") lazy val coursier = project("coursier")
.in(root) .in(root)
.aggregate( .aggregate(
catsJvm,
catsJs,
coreJvm, coreJvm,
coreJs, coreJs,
testsJvm, testsJvm,
@@ -0,0 +1,3 @@
package coursier.interop
abstract class PlatformCatsImplicits
@@ -0,0 +1,42 @@
package coursier.interop
import java.util.concurrent.ExecutorService
import _root_.cats.effect.IO
import _root_.cats.instances.vector._
import _root_.cats.syntax.apply._
import coursier.util.Schedulable
import scala.concurrent.{ExecutionContext, ExecutionContextExecutorService}
abstract class PlatformCatsImplicits {
// wish cs wasn't needed here (parSequence in gather needs it)
implicit def catsIOSchedulable(implicit cs: _root_.cats.effect.ContextShift[IO]): Schedulable[IO] =
new Schedulable[IO] {
def point[A](a: A) =
IO.pure(a)
def delay[A](a: => A) =
IO(a)
def handle[A](a: IO[A])(f: PartialFunction[Throwable, A]) =
a.handleErrorWith { e =>
f.lift(e).fold[IO[A]](IO.raiseError(e))(IO.pure)
}
def schedule[A](pool: ExecutorService)(f: => A) = {
val ec0 = pool match {
case eces: ExecutionContextExecutorService => eces
case _ => ExecutionContext.fromExecutorService(pool) // FIXME Is this instantiation costly? Cache it?
}
IO.shift(ec0) *> IO(f)
}
def gather[A](elems: Seq[IO[A]]) =
_root_.cats.Parallel.parSequence(elems.toVector).map(_.toSeq)
def bind[A, B](elem: IO[A])(f: A => IO[B]) =
elem.flatMap(f)
}
}
@@ -0,0 +1,55 @@
package coursier.interop
import _root_.cats.effect.IO
import coursier.{Module, moduleNameString, organizationString}
import coursier.interop.cats._
import coursier.test.compatibility.executionContext
import coursier.test.{TestRunner, compatibility}
import coursier.test.util.ToFuture
import utest._
import scala.concurrent.{ExecutionContext, Future}
object CatsTests extends TestSuite {
private implicit val cs = _root_.cats.effect.IO.contextShift(executionContext)
// few basic tests from CentralTests, to ensure everything is wired correctly with cats.effect.IO
private implicit val ioToFuture: ToFuture[IO] =
new ToFuture[IO] {
def toFuture[T](ec: ExecutionContext, f: IO[T]) =
Future(())
.flatMap(_ => f.unsafeToFuture())
}
private lazy val runner = new TestRunner(
artifact = compatibility.artifact[IO]
)
val tests = Tests {
'spark - {
* - runner.resolutionCheck(
Module(org"org.apache.spark", name"spark-core_2.11"),
"1.3.1",
profiles = Some(Set("hadoop-2.2"))
)
'scala210 - runner.resolutionCheck(
Module(org"org.apache.spark", name"spark-core_2.10"),
"2.1.1",
profiles = Some(Set("hadoop-2.6", "scala-2.10", "!scala-2.11"))
)
}
'argonautShapeless - {
runner.resolutionCheck(
Module(org"com.github.alexarchambault", name"argonaut-shapeless_6.1_2.11"),
"0.2.0"
)
}
}
}
@@ -0,0 +1,27 @@
package coursier.interop
import _root_.cats.instances.vector._
import coursier.util.{Gather, Monad}
object cats extends LowPriorityCatsImplicits {
implicit def coursierMonadFromCats[F[_]](implicit M: _root_.cats.Monad[F]): Monad[F] =
new Monad[F] {
def point[A](a: A) = M.pure(a)
def bind[A, B](elem: F[A])(f: A => F[B]) = M.flatMap(elem)(f)
}
}
abstract class LowPriorityCatsImplicits extends PlatformCatsImplicits {
implicit def coursierGatherFromCats[F[_], F0[_]](implicit N: _root_.cats.Monad[F], cs: _root_.cats.Parallel[F, F0]): Gather[F] =
new Gather[F] {
def point[A](a: A) = N.pure(a)
def bind[A, B](elem: F[A])(f: A => F[B]) = N.flatMap(elem)(f)
def gather[A](elems: Seq[F[A]]) = {
N.map(_root_.cats.Parallel.parSequence(elems.toVector))(_.toSeq)
}
}
}
@@ -11,6 +11,7 @@ object CrossDeps {
// The setting / .value hoop-and-loop is necessary because of the expansion of the %%% macro, which references // The setting / .value hoop-and-loop is necessary because of the expansion of the %%% macro, which references
// other settings. // other settings.
def catsEffect = setting("org.typelevel" %%% "cats-effect" % "1.0.0")
def fastParse = setting("com.lihaoyi" %%% "fastparse" % SharedVersions.fastParse) def fastParse = setting("com.lihaoyi" %%% "fastparse" % SharedVersions.fastParse)
def scalazCore = setting("org.scalaz" %%% "scalaz-core" % SharedVersions.scalaz) def scalazCore = setting("org.scalaz" %%% "scalaz-core" % SharedVersions.scalaz)
def scalaJsDom = setting("org.scala-js" %%% "scalajs-dom" % "0.9.6") def scalaJsDom = setting("org.scala-js" %%% "scalajs-dom" % "0.9.6")

0 comments on commit 3101909

Please sign in to comment.