Skip to content

Commit

Permalink
Merge pull request #514 from armanbilge/feature/lifters
Browse files Browse the repository at this point in the history
Add `Raise#fromEither` and friends
  • Loading branch information
djspiewak authored Feb 2, 2024
2 parents 5d623c2 + d12d72f commit 226f0b8
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 3 deletions.
7 changes: 6 additions & 1 deletion core/src/main/scala/cats/mtl/Ask.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package cats
package mtl

import cats.data.{Kleisli, ReaderWriterStateT => RWST}
import cats.data.{Kleisli, Reader, ReaderWriterStateT => RWST}
import cats.mtl.Ask.{const, AskImpl}
import cats.syntax.all._

Expand Down Expand Up @@ -51,6 +51,11 @@ trait Ask[F[_], +E] extends Serializable {
def ask[E2 >: E]: F[E2]

def reader[A](f: E => A): F[A] = applicative.map(ask)(f)

def fromReader[A](ra: Reader[E, A]): F[A] = reader(ra.run)

def fromKleisli[A](ka: Kleisli[F, E, A])(implicit F: FlatMap[F]): F[A] =
ask.flatMap(ka.run(_))
}

private[mtl] trait AskForMonadPartialOrder[F[_], G[_], E] extends Ask[G, E] {
Expand Down
13 changes: 13 additions & 0 deletions core/src/main/scala/cats/mtl/Raise.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ trait Raise[F[_], -E] extends Serializable {
def ensure[E2 <: E, A](fa: F[A])(error: => E2)(predicate: A => Boolean)(
implicit A: Monad[F]): F[A] =
A.flatMap(fa)(a => if (predicate(a)) A.pure(a) else raise(error))

def fromEither[A](ea: Either[E, A])(implicit F: Applicative[F]): F[A] =
ea.fold(raise, F.pure)

def fromEitherT[E2 <: E, A](ea: EitherT[F, E2, A])(implicit F: Monad[F]): F[A] =
F.flatMap(ea.value)(fromEither(_))

def fromOption[E2 <: E, A](oa: Option[A])(e: => E2)(implicit F: Applicative[F]): F[A] =
oa.fold[F[A]](raise(e))(F.pure)

def fromOptionT[E2 <: E, A](ota: OptionT[F, A])(e: => E2)(implicit F: Monad[F]): F[A] =
F.flatMap(ota.value)(oa => fromOption(oa)(e))

}

private[mtl] trait RaiseMonadPartialOrder[F[_], G[_], E] extends Raise[G, E] {
Expand Down
15 changes: 14 additions & 1 deletion core/src/main/scala/cats/mtl/Stateful.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package cats
package mtl

import cats.data.{ReaderWriterStateT => RWST, StateT}
import cats.data.{ReaderWriterStateT => RWST, State, StateT}

import scala.annotation.implicitNotFound

Expand Down Expand Up @@ -64,6 +64,19 @@ trait Stateful[F[_], S] extends Serializable {
def get: F[S]

def set(s: S): F[Unit]

def fromState[A](state: State[S, A]): F[A] =
monad.flatMap(get) { s0 =>
val (s1, a) = state.run(s0).value
monad.as(set(s1), a)
}

def fromStateT[A](state: StateT[F, S, A]): F[A] =
monad.flatMap(get) { s0 =>
monad.flatMap(state.run(s0)(monad)) { case (s1, a) =>
monad.as(set(s1), a)
}
}
}

private[mtl] trait LowPriorityStatefulInstances {
Expand Down
7 changes: 6 additions & 1 deletion core/src/main/scala/cats/mtl/Tell.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package cats
package mtl

import cats.data.{ReaderWriterStateT => RWST, WriterT}
import cats.data.{ReaderWriterStateT => RWST, Writer, WriterT}

import scala.annotation.implicitNotFound

Expand Down Expand Up @@ -47,6 +47,11 @@ trait Tell[F[_], -L] extends Serializable {
def writer[A](a: A, l: L): F[A] = functor.as(tell(l), a)

def tuple[A](ta: (L, A)): F[A] = writer(ta._2, ta._1)

def fromWriter[L2 <: L, A](wa: Writer[L2, A]): F[A] = tuple(wa.run)

def fromWriterT[L2 <: L, A](wa: WriterT[F, L2, A])(implicit F: FlatMap[F]): F[A] =
F.flatMap(wa.run)(tuple(_))
}

private[mtl] trait TellMonadPartialOrder[F[_], G[_], L] extends Tell[G, L] {
Expand Down

0 comments on commit 226f0b8

Please sign in to comment.