Created
January 27, 2017 06:21
-
-
Save rubenpieters/d154975fac5d0ca36c3082e7d4bf2878 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//------------------------- | |
// Monad Transformer | |
//------------------------- | |
import cats.data._ | |
import cats.implicits._ | |
import cats._ | |
type MonadStackStateTEither[ErrorType, StateType, ReturnType] = | |
StateT[Either[ErrorType, ?], StateType, ReturnType] | |
def decrMonadStackStateTEither: MonadStackStateTEither[String, Int, Unit] = for { | |
x <- StateT.get[Either[String, ?], Int] | |
_ <- if (x > 0) { StateT.set[Either[String, ?], Int](x - 1) } | |
else { StateT.lift[Either[String, ?], Int, Unit](Left("error")) } | |
} yield () | |
type MonadStackEitherTState[ErrorType, StateType, ReturnType] = | |
EitherT[State[StateType, ?], ErrorType, ReturnType] | |
def decrMonadStackEitherTState: MonadStackEitherTState[String, Int, Unit] = for { | |
x <- EitherT.liftT[State[Int, ?], String, Int](State.get[Int]) | |
_ <- if (x > 0) { EitherT.liftT[State[Int, ?], String, Unit](State.set(x - 1)) } | |
else { EitherT.left[State[Int, ?], String, Unit](State.pure("error")) } | |
} yield () | |
val resultStateTEither: Either[String, (Int, Unit)] = decrMonadStackStateTEither.run(0) | |
val resultEitherTState: (Int, Either[String, Unit]) = decrMonadStackEitherTState.value.run(0).value | |
println(resultStateTEither) | |
println(resultEitherTState) | |
//------------------------- | |
// mtl Monad Transformer | |
//------------------------- | |
// def decrMtlStateError[F[_]](implicit ms: MonadState[F, Int], me: MonadError[F, String]): F[Unit] = for { | |
// x <- ms.get | |
// _ <- if (x > 0) { ms.set(x - 1) } | |
// else { me.raiseError("error") } | |
// } yield () | |
def decrMtlStateError[F[_]](implicit ms: MonadState[F, Int], me: MonadError[F, String]): F[Unit] = { | |
ms.flatMap(ms.get) { x => | |
if (x > 0) { ms.set(x - 1) } | |
else { me.raiseError("error") } | |
} | |
} | |
implicit def monadStateEitherT[F[_], E, S](implicit ms: MonadState[F, S]): MonadState[EitherT[F, E, ?], S] = new MonadState[EitherT[F, E, ?], S] { | |
val F = Monad[F] | |
override def get: EitherT[F, E, S] = EitherT.liftT(ms.get) | |
override def set(s: S): EitherT[F, E, Unit] = EitherT.liftT(ms.set(s)) | |
// copied from cats EitherTMonad | |
override def pure[A](a: A): EitherT[F, E, A] = EitherT(F.pure(Either.right(a))) | |
override def flatMap[A, B](fa: EitherT[F, E, A])(f: A => EitherT[F, E, B]): EitherT[F, E, B] = fa flatMap f | |
override def tailRecM[A, B](a: A)(f: A => EitherT[F, E, Either[A, B]]): EitherT[F, E, B] = | |
EitherT(F.tailRecM(a)(a0 => F.map(f(a0).value) { | |
case Left(l) => Right(Left(l)) | |
case Right(Left(a1)) => Left(a1) | |
case Right(Right(b)) => Right(Right(b)) | |
})) | |
} | |
val resultMtlStateTEither: Either[String, (Int, Unit)] = decrMtlStateError[StateT[Either[String, ?], Int, ?]].run(0) | |
val resultMtlEitherTState: (Int, Either[String, Unit]) = decrMtlStateError[EitherT[State[Int, ?], String, ?]].value.run(0).value | |
println(resultMtlStateTEither) | |
println(resultMtlEitherTState) | |
//------------------------- | |
// Eff | |
//------------------------- | |
import org.atnos.eff._ | |
import org.atnos.eff.all._ | |
import org.atnos.eff.syntax.all._ | |
type _eitherString[R] = Either[String, ?] |= R | |
type _stateInt[R] = State[Int, ?] |= R | |
def decrEff[R : _eitherString : _stateInt]: Eff[R, Unit] = for { | |
x <- get | |
_ <- if (x > 0) { put(x - 1) } | |
else { left("error") } | |
} yield () | |
type FxStack = Fx.fx2[State[Int, ?], Either[String, ?]] | |
val resultRunStateRunEither: Either[String, (Unit, Int)] = decrEff[FxStack].runState(0).runEither.run | |
val resultRunEitherRunState: (Either[String, Unit], Int) = decrEff[FxStack].runEither.runState(0).run | |
println(resultRunStateRunEither) | |
println(resultRunEitherRunState) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment