Skip to content

Commit

Permalink
Add EitherT.cond, which is a friend of Either.cond
Browse files Browse the repository at this point in the history
  • Loading branch information
andyscott committed Nov 30, 2016
1 parent 25d11c4 commit 24c2be3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
24 changes: 24 additions & 0 deletions core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,30 @@ private[data] trait EitherTFunctions {
def apply[E, A](opt: Option[A], ifNone: => E)(implicit F: Applicative[F]): EitherT[F, E, A] =
EitherT(F.pure(Either.fromOption(opt, ifNone)))
}

/** If the condition is satisfied, return the given `A` in `Right`
* lifted into the specified `Applicative`, otherwise, return the
* given `E` in `Left` lifted into the specified `Applicative`.
*
* {{{
* scala> import cats.data._
* scala> import cats.instances.all._
* scala> import scala.concurrent.ExecutionContext.Implicits.global
* scala> val userInput = "hello world"
* scala> EitherT.cond[Future](
* userInput.forall(_.isDigit) && userInput.size == 10,
* userInput,
* s"The input $userInput does not look like a phone number")
* res0: EitherT[Future,String,String] =
* EitherT(Future(Success(Left(The input hello world does not look like a phone number))))
* }}}
*/
final def cond[F[_]]: CondPartiallyApplied[F] = new CondPartiallyApplied

final class CondPartiallyApplied[F[_]] private[EitherTFunctions] {
def apply[E, A](test: Boolean, right: => A, left: => E)(implicit F: Applicative[F]): EitherT[F, E, A] =
EitherT(F.pure(Either.cond(test, right, left)))
}
}

private[data] abstract class EitherTInstances extends EitherTInstances1 {
Expand Down
6 changes: 6 additions & 0 deletions tests/src/test/scala/cats/tests/EitherTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ class EitherTTests extends CatsSuite {
}
}

test("cond") {
forAll { (cond: Boolean, s: String, i: Int) =>
Either.cond(cond, s, i) should === (EitherT.cond[Id](cond, s, i).value)
}
}

test("isLeft negation of isRight") {
forAll { (eithert: EitherT[List, String, Int]) =>
eithert.isLeft should === (eithert.isRight.map(! _))
Expand Down

0 comments on commit 24c2be3

Please sign in to comment.