From 8c3898002805a70abfe8bd40d338ecdc5eef450a Mon Sep 17 00:00:00 2001 From: Oleg Skovpen Date: Wed, 10 May 2017 23:01:05 +0300 Subject: [PATCH] Add state method to MonadState and fromEither method to MonadError (#1651) * Add apply method to MonadState * Add fromEither --- .../main/scala/cats/ApplicativeError.scala | 18 ++++++++++++++++ core/src/main/scala/cats/MonadState.scala | 21 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/core/src/main/scala/cats/ApplicativeError.scala b/core/src/main/scala/cats/ApplicativeError.scala index 4f36625205..61ab4b6604 100644 --- a/core/src/main/scala/cats/ApplicativeError.scala +++ b/core/src/main/scala/cats/ApplicativeError.scala @@ -104,6 +104,24 @@ trait ApplicativeError[F[_], E] extends Applicative[F] { case Success(a) => pure(a) case Failure(e) => raiseError(e) } + + /** + * Convert from scala.Either + * + * Example: + * {{{ + * scala> import cats.ApplicativeError + * scala> import cats.instances.option._ + * + * scala> ApplicativeError[Option, Unit].fromEither(Right(1)) + * res0: scala.Option[Int] = Some(1) + * + * scala> ApplicativeError[Option, Unit].fromEither(Left(())) + * res1: scala.Option[Nothing] = None + * }}} + */ + def fromEither[A](x: E Either A): F[A] = + x.fold(raiseError, pure) } object ApplicativeError { diff --git a/core/src/main/scala/cats/MonadState.scala b/core/src/main/scala/cats/MonadState.scala index 4539971d5f..abc45d4488 100644 --- a/core/src/main/scala/cats/MonadState.scala +++ b/core/src/main/scala/cats/MonadState.scala @@ -17,6 +17,27 @@ package cats * }}} */ trait MonadState[F[_], S] extends Monad[F] { + + /** + * Embed a state action into the monad. + * + * Example: + * {{{ + * scala> import cats.MonadState + * scala> import cats.data.StateT + * scala> import cats.instances.list._ + * + * scala> val M = MonadState[StateT[List, Int, ?], Int] + * scala> import M._ + * + * scala> val st: StateT[List, Int, Int] = state(s => (s + 1, s * 100)) + * scala> st.run(1) + * res0: List[(Int, Int)] = List((2,100)) + * }}} + */ + def state[A](f: S => (S, A)): F[A] = + flatMap(get)(s => f(s) match { case (s, a) => map(set(s))(_ => a) }) + def get: F[S] def set(s: S): F[Unit]