Skip to content

Commit

Permalink
Merge pull request #2293 from kailuowang/fromValidated
Browse files Browse the repository at this point in the history
added `liftTo` syntax to `Validated`
  • Loading branch information
johnynek authored Jun 13, 2018
2 parents 1d7ee78 + 49c5d9f commit c712a65
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 3 deletions.
7 changes: 6 additions & 1 deletion core/src/main/scala/cats/ApplicativeError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@ trait ApplicativeError[F[_], E] extends Applicative[F] {
* }}}
*/
def fromEither[A](x: E Either A): F[A] =
x.fold(raiseError, pure)
x match {
case Right(a) => pure(a)
case Left(e) => raiseError(e)
}


}

object ApplicativeError {
Expand Down
1 change: 1 addition & 0 deletions core/src/main/scala/cats/syntax/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ trait AllSyntaxBinCompat1
with NestedSyntax
with BinestedSyntax
with ParallelFlatSyntax
with ValidatedExtensionSyntax
24 changes: 23 additions & 1 deletion core/src/main/scala/cats/syntax/applicativeError.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats
package syntax

import cats.data.EitherT
import cats.data.Validated.{Invalid, Valid}
import cats.data.{EitherT, Validated}

trait ApplicativeErrorSyntax {
implicit final def catsSyntaxApplicativeErrorId[E](e: E): ApplicativeErrorIdOps[E] =
Expand Down Expand Up @@ -42,6 +43,27 @@ final class ApplicativeErrorExtensionOps[F[_], E](F: ApplicativeError[F, E]) {
def fromOption[A](oa: Option[A], ifEmpty: => E): F[A] =
ApplicativeError.liftFromOption(oa, ifEmpty)(F)

/**
* Convert from cats.data.Validated
*
* Example:
* {{{
* scala> import cats.implicits._
* scala> import cats.ApplicativeError
*
* scala> ApplicativeError[Option, Unit].fromValidated(1.valid[Unit])
* res0: scala.Option[Int] = Some(1)
*
* scala> ApplicativeError[Option, Unit].fromValidated(().invalid[Int])
* res1: scala.Option[Int] = None
* }}}
*/
def fromValidated[A](x: Validated[E, A]): F[A] =
x match {
case Invalid(e) => F.raiseError(e)
case Valid(a) => F.pure(a)
}

}

final class ApplicativeErrorIdOps[E](val e: E) extends AnyVal {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/syntax/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ package object syntax {
object traverse extends TraverseSyntax
object nonEmptyTraverse extends NonEmptyTraverseSyntax
object unorderedTraverse extends UnorderedTraverseSyntax
object validated extends ValidatedSyntax
object validated extends ValidatedSyntax with ValidatedExtensionSyntax
object vector extends VectorSyntax
object writer extends WriterSyntax
}
10 changes: 10 additions & 0 deletions core/src/main/scala/cats/syntax/validated.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,13 @@ final class ValidatedIdSyntax[A](val a: A) extends AnyVal {
def invalid[B]: Validated[A, B] = Validated.Invalid(a)
def invalidNel[B]: ValidatedNel[A, B] = Validated.invalidNel(a)
}

trait ValidatedExtensionSyntax {
implicit final def catsSyntaxValidatedExtension[E, A](v: Validated[E, A]): ValidatedExtension[E, A] =
new ValidatedExtension(v)
}

final class ValidatedExtension[E, A](val self: Validated[E, A]) extends AnyVal {
def liftTo[F[_]](implicit F: ApplicativeError[F, E]): F[A] =
new ApplicativeErrorExtensionOps(F).fromValidated(self)
}
6 changes: 6 additions & 0 deletions tests/src/test/scala/cats/tests/ValidatedSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,10 @@ class ValidatedSuite extends CatsSuite {
Validated.condNel(cond, s, i) should === (Either.cond(cond, s, i).toValidatedNel)
}
}

test("liftTo consistent with direct to Option") {
forAll { (v: Validated[Unit, Int]) =>
v.liftTo[Option] shouldBe v.toOption
}
}
}

0 comments on commit c712a65

Please sign in to comment.