Skip to content

Commit

Permalink
Add Parallel instance for Ior
Browse files Browse the repository at this point in the history
  • Loading branch information
andyscott committed Dec 1, 2017
1 parent f29dc72 commit d4f7d01
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
36 changes: 36 additions & 0 deletions core/src/main/scala/cats/data/Ior.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cats
package data

import cats.Bifunctor
import cats.arrow.FunctionK
import cats.data.Validated.{Invalid, Valid}

import scala.annotation.tailrec
Expand Down Expand Up @@ -203,6 +204,41 @@ private[data] sealed abstract class IorInstances extends IorInstances0 {
new Bifunctor[Ior] {
override def bimap[A, B, C, D](fab: A Ior B)(f: A => C, g: B => D): C Ior D = fab.bimap(f, g)
}

implicit def parallelForIor[E]
(implicit E: Semigroup[E]): Parallel[Ior[E, ?], Ior[E, ?]] = new Parallel[Ior[E, ?], Ior[E, ?]]
{

private[this] val identityK: Ior[E, ?] ~> Ior[E, ?] = FunctionK.id

def parallel: Ior[E, ?] ~> Ior[E, ?] = identityK
def sequential: Ior[E, ?] ~> Ior[E, ?] = identityK

val applicative: Applicative[Ior[E, ?]] = new Applicative[Ior[E, ?]] {
def pure[A](a: A): Ior[E, A] = Ior.right(a)
def ap[A, B](ff: Ior[E, A => B])(fa: Ior[E, A]): Ior[E, B] =
fa match {
case Ior.Right(a) => ff match {
case Ior.Right(f) => Ior.Right(f(a))
case Ior.Both(e1, f) => Ior.Both(e1, f(a))
case Ior.Left(e1) => Ior.Left(e1)
}
case Ior.Both(e1, a) => ff match {
case Ior.Right(f) => Ior.Both(e1, f(a))
case Ior.Both(e2, f) => Ior.Both(E.combine(e2, e1), f(a))
case Ior.Left(e2) => Ior.Left(E.combine(e2, e1))
}
case Ior.Left(e1) => ff match {
case Ior.Right(f) => Ior.Left(e1)
case Ior.Both(e2, f) => Ior.Left(E.combine(e2, e1))
case Ior.Left(e2) => Ior.Left(E.combine(e2, e1))
}
}
}
lazy val monad: Monad[Ior[E, ?]] = Monad[Ior[E, ?]]
}


}

private[data] sealed abstract class IorInstances0 {
Expand Down
19 changes: 17 additions & 2 deletions tests/src/test/scala/cats/tests/ParallelSuite.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

package cats
package tests

Expand All @@ -17,7 +16,7 @@ import scala.collection.immutable.SortedSet
class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest {


test("ParTraversing Either should accumulate errors") {
test("ParSequence Either should accumulate errors") {
forAll { es: List[Either[String, Int]] =>
val lefts = es.collect {
case Left(e) => e
Expand All @@ -27,6 +26,21 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest {
}
}

test("ParSequence Ior should accumulate errors") {
forAll { es: List[Ior[String, Int]] =>
val lefts = es.map(_.left).collect {
case Some(e) => e
}.foldMap(identity)
es.parSequence.left.getOrElse(Monoid[String].empty) should === (lefts)
}
}

test("ParSequence Ior should sequence values") {
forAll { es: List[Ior[String, Int]] =>
es.parSequence.right should === (es.map(_.toOption).sequence)
}
}

test("ParTraverse identity should be equivalent to parSequence") {
forAll { es: List[Either[String, Int]] =>
es.parTraverse(identity) should === (es.parSequence)
Expand Down Expand Up @@ -156,6 +170,7 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest {
}

checkAll("Parallel[Either[String, ?], Validated[String, ?]]", ParallelTests[Either[String, ?], Validated[String, ?]].parallel[Int, String])
checkAll("Parallel[Ior[String, ?], Ior[String, ?]]", ParallelTests[Ior[String, ?], Ior[String, ?]].parallel[Int, String])
checkAll("Parallel[OptionT[M, ?], Nested[F, Option, ?]]", ParallelTests[OptionT[Either[String, ?], ?], Nested[Validated[String, ?], Option, ?]].parallel[Int, String])
checkAll("Parallel[EitherT[M, String, ?], Nested[F, Validated[String, ?], ?]]", ParallelTests[EitherT[Either[String, ?], String, ?], Nested[Validated[String, ?], Validated[String, ?], ?]].parallel[Int, String])
checkAll("Parallel[EitherT[Option, String, ?], Nested[Option, Validated[String, ?], ?]]", ParallelTests[EitherT[Option, String, ?], Nested[Option, Validated[String, ?], ?]].parallel[Int, String])
Expand Down

0 comments on commit d4f7d01

Please sign in to comment.