Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add syntax to create a XorT from an F[A] and from a Xor. #1155

Merged
merged 1 commit into from
Jun 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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