Skip to content
This repository has been archived by the owner on Feb 27, 2021. It is now read-only.

Commit

Permalink
Implement Parallel[Task, ParallelTask] instance
Browse files Browse the repository at this point in the history
  • Loading branch information
joroKr21 committed Jan 29, 2019
1 parent 90a8c15 commit f71bc00
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
target/
.idea/

# vim
*.sw?
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}

ThisBuild / baseVersion := "1.7"
ThisBuild / baseVersion := "1.8"

ThisBuild / strictSemVer := false // 😢 maybe in 2.0...

Expand Down
1 change: 1 addition & 0 deletions effect/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ The reason for this is implicit ambiguity. `Effect` is a subtype of `cats.Monad`
### Instances

- `Effect[scalaz.concurrent.Task]`
- `Parallel[scalaz.concurrent.Task, scalaz.concurrent.Task.ParallelTask]`
- `Sync[scalaz.effect.IO]`

Don't use `scalaz.effect.IO`. Honestly. It's strictly worse than every other option out there. Search/replace your imports today.
Expand Down
14 changes: 12 additions & 2 deletions effect/src/main/scala/shims/effect/instances/TaskInstances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@

package shims.effect.instances

import cats.StackSafeMonad
import cats.{Applicative, Monad, Parallel, StackSafeMonad, ~>}
import cats.effect.{Effect, ExitCase, IO, SyncIO}

import scalaz.{\/, -\/, \/-}
import scalaz.{Tag, -\/, \/, \/-}
import scalaz.concurrent.Task.ParallelTask
import scalaz.concurrent.{Future, Task}

import shims.conversions.MonadErrorConversions
Expand Down Expand Up @@ -95,6 +96,15 @@ trait TaskInstances extends MonadErrorConversions {
def suspend[A](thunk: => Task[A]): Task[A] = Task.suspend(thunk)
}

implicit val taskParallel: Parallel[Task, ParallelTask] = new Parallel[Task, ParallelTask] {
import Task.taskParallelApplicativeInstance

val monad: Monad[Task] = taskEffect
val applicative: Applicative[ParallelTask] = Applicative[ParallelTask]
val sequential: ParallelTask ~> Task = λ[ParallelTask ~> Task](Tag.unwrap(_))
val parallel: Task ~> ParallelTask = λ[Task ~> ParallelTask](Tag(_))
}

private def functionToPartial[A, B](f: A => B): PartialFunction[A, B] = _ match {
case a => f(a)
}
Expand Down
6 changes: 5 additions & 1 deletion effect/src/test/scala/shims/effect/TaskArbitrary.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

package shims.effect

import scalaz.\/
import scalaz.{Tag, \/}
import scalaz.concurrent.Task
import scalaz.concurrent.Task.ParallelTask

import org.scalacheck._

Expand All @@ -26,6 +27,9 @@ object TaskArbitrary {
implicit def arbitraryTask[A: Arbitrary: Cogen]: Arbitrary[Task[A]] =
Arbitrary(Gen.delay(genTask[A]))

implicit def arbitraryParallelTask[A: Arbitrary: Cogen]: Arbitrary[ParallelTask[A]] =
Tag.subst(arbitraryTask[A])

// TODO
implicit def cogenTask[A]: Cogen[Task[A]] =
Cogen[Unit].contramap(_ => ())
Expand Down
21 changes: 19 additions & 2 deletions effect/src/test/scala/shims/effect/TaskInstancesSpecs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package shims.effect

import cats.Eq
import cats.laws.discipline.{ApplicativeTests, ParallelTests}

import cats.effect.IO
import cats.effect.laws.discipline.{arbitrary, EffectTests}, arbitrary._
Expand All @@ -27,7 +28,9 @@ import cats.instances.int._
import cats.instances.tuple._
import cats.instances.unit._

import scalaz.Tag
import scalaz.concurrent.Task
import scalaz.concurrent.Task.ParallelTask

import org.specs2.Specification
import org.specs2.scalacheck.Parameters
Expand All @@ -38,9 +41,20 @@ import org.typelevel.discipline.specs2.Discipline

object TaskInstancesSpecs extends Specification with Discipline {
import TaskArbitrary._
import Task.taskParallelApplicativeInstance

def is =
br ^ checkAllAsync("Task", implicit ctx => EffectTests[Task].effect[Int, Int, Int])
def is = br ^ taskEff ^ br ^ taskPar ^ br ^ parTaskApp

def taskEff = checkAllAsync("Effect[Task]",
implicit ctx => EffectTests[Task].effect[Int, Int, Int])

def taskPar = checkAllAsync("Parallel[Task, ParallelTask]",
implicit ctx => ParallelTests[Task, ParallelTask].parallel[Int, Int])

def parTaskApp = checkAllAsync("Parallel[Task, ParallelTask]", { implicit ctx =>
val tests = ApplicativeTests[ParallelTask]
tests.applicative[Int, Int, Int]
})

def checkAllAsync(name: String, f: TestContext => Laws#RuleSet)(implicit p: Parameters) = {
val context = TestContext()
Expand All @@ -54,4 +68,7 @@ object TaskInstancesSpecs extends Specification with Discipline {

implicit def taskEq[A: Eq](implicit ctx: TestContext): Eq[Task[A]] =
Eq.by(ta => IO.async[A](k => ta.unsafePerformAsync(e => k(e.toEither))))

implicit def parallelTaskEq[A: Eq](implicit ctx: TestContext): Eq[ParallelTask[A]] =
Tag.subst(taskEq[A])
}

0 comments on commit f71bc00

Please sign in to comment.