Skip to content

Commit

Permalink
Add syntax to create a XorT from an F[A] and from a Xor.
Browse files Browse the repository at this point in the history
  • Loading branch information
peterneyens committed Jun 30, 2016
1 parent c4f5d1c commit 258fac6
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 3 deletions.
17 changes: 17 additions & 0 deletions core/src/main/scala/cats/data/Xor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import scala.util.{Failure, Success, Try}
* `flatMap` apply only in the context of the "right" case. This right bias makes [[Xor]] more convenient to use
* than `scala.Either` in a monadic context. Methods such as `swap`, and `leftMap` provide functionality
* that `scala.Either` exposes through left projections.
*
* Some additional [[Xor]] methods can be found in [[Xor.XorOps XorOps]]. These methods are not defined on [[Xor]] itself because
* [[Xor]] is covariant in its types `A` and `B`.
*/
sealed abstract class Xor[+A, +B] extends Product with Serializable {

Expand Down Expand Up @@ -188,6 +191,20 @@ sealed abstract class Xor[+A, +B] extends Product with Serializable {
object Xor extends XorInstances with XorFunctions {
final case class Left[+A](a: A) extends (A Xor Nothing)
final case class Right[+B](b: B) extends (Nothing Xor B)

final implicit class XorOps[A, B](val value: A Xor B) extends AnyVal {
/**
* Transform the `Xor` into a [[XorT]] while lifting it into the specified Applicative.
*
* {{{
* scala> import cats.implicits._
* scala> val x: Xor[String, Int] = Xor.right(3)
* scala> x.toXorT[Option]
* res0: cats.data.XorT[Option, String, Int] = XorT(Some(Right(3)))
* }}}
*/
def toXorT[F[_]: Applicative]: XorT[F, A, B] = XorT.fromXor(value)
}
}

private[data] sealed abstract class XorInstances extends XorInstances1 {
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/scala/cats/syntax/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ trait AllSyntax
with ComonadSyntax
with ComposeSyntax
with ContravariantSyntax
with CoproductSyntax
with EitherSyntax
with EqSyntax
with FlatMapSyntax
Expand All @@ -37,7 +38,7 @@ trait AllSyntax
with StrongSyntax
with TransLiftSyntax
with TraverseSyntax
with XorSyntax
with ValidatedSyntax
with CoproductSyntax
with WriterSyntax
with XorSyntax
with XorTSyntax
3 changes: 2 additions & 1 deletion core/src/main/scala/cats/syntax/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ package object syntax {
object strong extends StrongSyntax
object transLift extends TransLiftSyntax
object traverse extends TraverseSyntax
object xor extends XorSyntax
object validated extends ValidatedSyntax
object writer extends WriterSyntax
object xor extends XorSyntax
object xort extends XorTSyntax
}
39 changes: 39 additions & 0 deletions core/src/main/scala/cats/syntax/xort.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package cats
package syntax

import cats.data.XorT

trait XorTSyntax extends XorTSyntax1 {
implicit def catsSyntaxXorT[F[_]: Functor, A](fa: F[A]): XorTFunctorOps[F, A] = new XorTFunctorOps(fa)
}

private[syntax] trait XorTSyntax1 {
implicit def catsSyntaxUXorT[FA](fa: FA)(implicit U: Unapply[Functor, FA]): XorTFunctorOps[U.M, U.A] =
new XorTFunctorOps[U.M, U.A](U.subst(fa))(U.TC)
}

final class XorTFunctorOps[F[_]: Functor, A](val fa: F[A]) {
/**
* Lift this `F[A]` into a `XorT[F, A, R]`.
*
* {{{
* scala> import cats.implicits._
* scala> val oa: Option[String] = Some("boo")
* scala> oa.leftXorT[Int]
* res0: cats.data.XorT[Option,String,Int] = XorT(Some(Left(boo)))
* }}}
*/
def leftXorT[R]: XorT[F, A, R] = XorT.left(fa)

/**
* Lift this `F[A]` into a `XorT[F, L, A]`.
*
* {{{
* scala> import cats.implicits._
* scala> val oa: Option[Int] = Some(1)
* scala> oa.rightXorT[String]
* res0: cats.data.XorT[Option,String,Int] = XorT(Some(Right(1)))
* }}}
*/
def rightXorT[L]: XorT[F, L, A] = XorT.right(fa)
}
1 change: 1 addition & 0 deletions tests/src/test/scala/cats/tests/XorTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class XorTests extends CatsSuite {
x.isLeft should === (x.toList.isEmpty)
x.isLeft should === (x.toValidated.isInvalid)
x.isLeft should === (x.toValidatedNel.isInvalid)
Option(x.isLeft) should === (x.toXorT[Option].isLeft)
}
}

Expand Down

0 comments on commit 258fac6

Please sign in to comment.