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 EitherT.liftAttemptK #3374

Merged
merged 1 commit into from
Mar 31, 2020
Merged
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
19 changes: 19 additions & 0 deletions core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,25 @@ object EitherT extends EitherTInstances {
final def liftK[F[_], A](implicit F: Functor[F]): F ~> EitherT[F, A, *] =
new (F ~> EitherT[F, A, *]) { def apply[B](fb: F[B]): EitherT[F, A, B] = right(fb) }

/**
* Lifts an effect into EitherT, catching all errors from the effect and lifting them into EitherT's error channel.
*
* {{{
* scala> import cats._, data._, implicits._
* scala> val a: Option[Int] = None
* scala> val b: EitherT[Option, Unit, Int] = EitherT.liftAttemptK[Option, Unit].apply(a)
* scala> b.value
* res0: Option[Either[Unit, Int]] = Some(Left(()))
*
* scala> val a2: Option[Int] = Some(42)
* scala> val b2: EitherT[Option, Unit, Int] = EitherT.liftAttemptK[Option, Unit].apply(a2)
* scala> b2.value
* res1: Option[Either[Unit, Int]] = Some(Right(42))
* }}}
*/
final def liftAttemptK[F[_], E](implicit F: ApplicativeError[F, E]): F ~> EitherT[F, E, *] =
λ[F ~> EitherT[F, E, *]](fa => EitherT(F.attempt(fa)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've been removing the value-level kind-projector syntax for polymorphic functions, since there's no real possibility of it ever cross-building on Dotty, and since writing this out explicitly as:

new (F ~> EitherT[F, E, *]) { def apply[A](fa: F[A]): EitherT[F, E, A] = EitherT(F.attempt(fa)) }

…is only marginally less readable. I don't think that needs to be changed in this PR, though, since we're not actually cross-building on Dotty yet.

(Note that the type-level λ is fine on Dotty with -Ykind-projector.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I was under the impression this was also part of the -Ykind-projector feature. But it makes sense, I'll keep it in mind.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kubukoz No, I hate kind-projector's value-level lambda syntax and couldn't be bothered to implement it in -Ykind-projector. 😄 (Also it would have required much more disruptive changes than anything else that made it into -Ykind-projector.)


@deprecated("Use EitherT.liftF.", "1.0.0-RC1")
final def liftT[F[_], A, B](fb: F[B])(implicit F: Functor[F]): EitherT[F, A, B] = right(fb)

Expand Down