scala.util.Either Scala Examples
The following examples show how to use scala.util.Either.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: refs.scala From benchmarks with Apache License 2.0 | 5 votes |
import sbt._ import scala.util.{Either, Left, Right} trait Fs2Refs { def repo: Either[URI, File] lazy val fs2Core = repo.fold(ProjectRef(_, "coreJVM"), ProjectRef(_, "coreJVM")) lazy val fs2IO = repo.fold(ProjectRef(_, "io"), ProjectRef(_, "io")) } object github extends Fs2Refs { val repo = Left(uri("git://github.com/functional-streams-for-scala/fs2.git#01ec76b")) } object local extends Fs2Refs { val repo = Right(file("..") / "fs2") }
Example 2
Source File: RerunnableInstances.scala From catbird with Apache License 2.0 | 5 votes |
package io.catbird.util.effect import cats.effect.{ Effect, ExitCase, IO, SyncIO } import com.twitter.util.{ Future, Monitor, Promise, Return, Throw } import io.catbird.util.{ Rerunnable, RerunnableMonadError } import java.lang.Throwable import scala.Unit import scala.util.{ Either, Left, Right } trait RerunnableInstances { implicit final val rerunnableEffectInstance: Effect[Rerunnable] = new RerunnableMonadError with Effect[Rerunnable] { final def suspend[A](thunk: => Rerunnable[A]): Rerunnable[A] = Rerunnable.suspend[A](thunk) override final def delay[A](thunk: => A): Rerunnable[A] = Rerunnable[A](thunk) final def async[A](k: (Either[Throwable, A] => Unit) => Unit): Rerunnable[A] = new Rerunnable[A] { final def run: Future[A] = { val promise = new Promise[A] k { e => if (promise.isDefined) () else e match { case Right(a) => promise.setValue(a) case Left(err) => promise.setException(err) } } promise } } final def asyncF[A](k: (Either[Throwable, A] => Unit) => Rerunnable[Unit]): Rerunnable[A] = new Rerunnable[A] { final def run: Future[A] = { val promise = new Promise[A] val rerunnable = k { e => if (promise.isDefined) () else e match { case Right(a) => promise.setValue(a) case Left(err) => promise.setException(err) } } rerunnable.run.flatMap(_ => promise) } } final def runAsync[A](fa: Rerunnable[A])(cb: Either[Throwable, A] => IO[Unit]): SyncIO[Unit] = rerunnableToIO[A](fa).runAsync(cb) final def bracketCase[A, B](acquire: Rerunnable[A])(use: A => Rerunnable[B])( release: (A, ExitCase[Throwable]) => Rerunnable[Unit] ): Rerunnable[B] = new Rerunnable[B] { final def run: Future[B] = acquire.run.flatMap { a => val future = use(a).run future.transform { case Return(b) => release(a, ExitCase.complete).run.handle(Monitor.catcher).flatMap(_ => future) case Throw(err) => release(a, ExitCase.error(err)).run.handle(Monitor.catcher).flatMap(_ => future) } } } } }
Example 3
package io.catbird.util import cats.{ CoflatMap, Comonad, Eq, Monad, Monoid, Semigroup } import com.twitter.util.Var import scala.Boolean import scala.util.{ Either, Left, Right } trait VarInstances extends VarInstances1 { implicit final val twitterVarInstance: Monad[Var] with CoflatMap[Var] = new VarCoflatMap with Monad[Var] { final def pure[A](x: A): Var[A] = Var.value(x) final def flatMap[A, B](fa: Var[A])(f: A => Var[B]): Var[B] = fa.flatMap(f) override final def map[A, B](fa: Var[A])(f: A => B): Var[B] = fa.map(f) } implicit final def twitterVarSemigroup[A](implicit A: Semigroup[A]): Semigroup[Var[A]] = new VarSemigroup[A] final def varEq[A](implicit A: Eq[A]): Eq[Var[A]] = new Eq[Var[A]] { final def eqv(fx: Var[A], fy: Var[A]): Boolean = Var.sample( fx.join(fy).map { case (x, y) => A.eqv(x, y) } ) } } trait VarInstances1 { final def varComonad: Comonad[Var] = new VarCoflatMap with Comonad[Var] { final def extract[A](x: Var[A]): A = Var.sample(x) final def map[A, B](fa: Var[A])(f: A => B): Var[B] = fa.map(f) } implicit final def twitterVarMonoid[A](implicit A: Monoid[A]): Monoid[Var[A]] = new VarSemigroup[A] with Monoid[Var[A]] { final def empty: Var[A] = Var.value(A.empty) } } private[util] abstract class VarCoflatMap extends CoflatMap[Var] { final def coflatMap[A, B](fa: Var[A])(f: Var[A] => B): Var[B] = Var(f(fa)) final def tailRecM[A, B](a: A)(f: A => Var[Either[A, B]]): Var[B] = f(a).flatMap { case Left(a1) => tailRecM(a1)(f) case Right(b) => Var.value(b) } } private[util] class VarSemigroup[A](implicit A: Semigroup[A]) extends Semigroup[Var[A]] { final def combine(fx: Var[A], fy: Var[A]): Var[A] = fx.join(fy).map { case (x, y) => A.combine(x, y) } }
Example 4
package io.catbird.util import cats.{ Applicative, CoflatMap, Eq, Eval, MonadError, Monoid, Semigroup, Traverse } import com.twitter.util.{ Return, Throw, Try } import java.lang.Throwable import scala.{ Boolean, inline } import scala.annotation.tailrec import scala.util.{ Either, Left, Right } trait TryInstances extends TryInstances1 { implicit final def twitterTryEq[A](implicit A: Eq[A], T: Eq[Throwable]): Eq[Try[A]] = new Eq[Try[A]] { def eqv(x: Try[A], y: Try[A]): Boolean = (x, y) match { case (Throw(xError), Throw(yError)) => T.eqv(xError, yError) case (Return(xValue), Return(yValue)) => A.eqv(xValue, yValue) case _ => false } } implicit final def twitterTrySemigroup[A](implicit A: Semigroup[A]): Semigroup[Try[A]] = new TrySemigroup[A] implicit final val twitterTryInstance: MonadError[Try, Throwable] with CoflatMap[Try] with Traverse[Try] = new MonadError[Try, Throwable] with CoflatMap[Try] with Traverse[Try] { final def pure[A](x: A): Try[A] = Return(x) final def flatMap[A, B](fa: Try[A])(f: A => Try[B]): Try[B] = fa.flatMap(f) override final def map[A, B](fa: Try[A])(f: A => B): Try[B] = fa.map(f) final def handleErrorWith[A](fa: Try[A])(f: Throwable => Try[A]): Try[A] = fa.rescue { case e => f(e) } final def raiseError[A](e: Throwable): Try[A] = Throw(e) final def coflatMap[A, B](ta: Try[A])(f: Try[A] => B): Try[B] = Try(f(ta)) final def foldLeft[A, B](fa: Try[A], b: B)(f: (B, A) => B): B = fa match { case Return(a) => f(b, a) case Throw(_) => b } final def foldRight[A, B](fa: Try[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa match { case Return(a) => f(a, lb) case Throw(_) => lb } final def traverse[G[_], A, B](fa: Try[A])(f: A => G[B])(implicit G: Applicative[G]): G[Try[B]] = fa match { case Return(a) => G.map(f(a))(Return(_)) case t: Throw[_] => G.pure(TryInstances.castThrow[B](t)) } @tailrec final def tailRecM[A, B](a: A)(f: A => Try[Either[A, B]]): Try[B] = f(a) match { case t: Throw[_] => TryInstances.castThrow[B](t) case Return(Left(a1)) => tailRecM(a1)(f) case Return(Right(b)) => Return(b) } } } private[util] final object TryInstances { @inline final def castThrow[A](t: Throw[_]): Try[A] = t.asInstanceOf[Try[A]] } private[util] trait TryInstances1 { implicit final def twitterTryMonoid[A](implicit A: Monoid[A]): Monoid[Try[A]] = new TrySemigroup[A] with Monoid[Try[A]] { final def empty: Try[A] = Return(A.empty) } } private[util] class TrySemigroup[A](implicit A: Semigroup[A]) extends Semigroup[Try[A]] { final def combine(fx: Try[A], fy: Try[A]): Try[A] = fx.flatMap(x => fy.map(y => A.combine(x, y))) }
Example 5
Source File: JsonInnerEngine.scala From Soteria with MIT License | 5 votes |
package com.leobenkel.soteria.Utils.Json import com.github.ghik.silencer.silent import com.leobenkel.soteria.Utils.Json.FilterNulls._ import com.leobenkel.soteria.Utils.Json.JsonDecode.Encoder import scala.util.parsing.json._ import scala.util.{Either, Left, Right, Try} @silent("deprecated") private[Json] object JsonInnerEngine { def parse[A]( input: String, parser: JsonDecode.Parser[A] ): Either[String, A] = { Try( JSON .parseFull(input) .map(_.asInstanceOf[Map[String, Any]]) ).toEither.left .map(_.toString) .right.flatMap { case None => Left("Did not parse") case Some(v) => parser(v) match { case Right(vv) => Right(vv) case Left(ex) => Left(s"The parser failed: $ex") } } } private def unsafeConvert[A <: Encoder](input: A): Map[String, Any] = { input.toJsonStructure.right.get } private def convert(input: Map[_, _]): Map[String, Any] = { input.filterNullsOut .mapValues { case v: JsonDecode.Encoder => JSONObject(convert(unsafeConvert(v))) case v: Map[_, _] => JSONObject(convert(v)) case v: List[_] => JSONArray(v) case v => v } } def encode[A <: Encoder](input: A): Either[String, String] = { input.toJsonStructure.right .flatMap( inputMap => Try( JSONObject .apply(convert(inputMap)) .toString(JSONFormat.defaultFormatter) ).toEither.left .map(_.toString) ) } }
Example 6
Source File: Results.scala From parseback with Apache License 2.0 | 5 votes |
package parseback import util.Catenable import util.Catenable.Syntax import scala.util.{Either, Left, Right} // semantics must mirror Nullable sealed trait Results[+A] { import Results._ final def map[B](f: A => B): Results[B] = this pmap { _ map f } final def pmap[B](f: Catenable[A] => Catenable[B]): Results[B] = this match { case Success(values) => Success(f(values)) case Failure(errors) => Failure(errors) case Hypothetical(errors) => Hypothetical(errors) } // error merging is not commutative final def &&[B](that: Results[B]): Results[(A, B)] = (this, that) match { case (Success(v1), Success(v2)) => Success(v1 flatMap { a => v2 map { b => (a, b) } }) case (Success(_), Failure(e)) => Failure(e) case (Failure(e), Success(_)) => Failure(e) case (Failure(e), Failure(_)) => Failure(e) case (Failure(e), Hypothetical(_)) => Failure(e) case (Hypothetical(h), Failure(_)) => Failure(h) case (Success(_), Hypothetical(h)) => Hypothetical(h) case (Hypothetical(h), Success(_)) => Hypothetical(h) case (Hypothetical(h1), Hypothetical(h2)) => Hypothetical(ParseError.prioritize(h1 ::: h2)) } final def ||[B >: A](that: Results[B]): Results[B] = (this, that) match { case (Success(v1), Success(v2)) => Success(v1 ++ v2) case (Success(v), Failure(_)) => Success(v) case (Failure(_), Success(v)) => Success(v) case (Failure(e1), Failure(e2)) => Failure(ParseError.prioritize(e1 ::: e2)) case (Failure(e), Hypothetical(h)) => Hypothetical(ParseError.prioritize(e ::: h)) case (Hypothetical(h), Failure(e)) => Hypothetical(ParseError.prioritize(e ::: h)) case (Success(v), Hypothetical(_)) => Success(v) case (Hypothetical(_), Success(v)) => Success(v) case (Hypothetical(h1), Hypothetical(h2)) => Hypothetical(ParseError.prioritize(h1 ::: h2)) } final def toEither: Either[List[ParseError], Catenable[A]] = this match { case Success(results) => Right(results) case Failure(errors) => Left(errors) case Hypothetical(errors) => Left(errors) } } object Results { sealed trait Cacheable[+A] extends Results[A] final case class Success[+A](values: Catenable[A]) extends Cacheable[A] final case class Failure(errors: List[ParseError]) extends Cacheable[Nothing] final case class Hypothetical(errors: List[ParseError]) extends Results[Nothing] }
Example 7
Source File: EitherMatchers.scala From cats-scalatest with Apache License 2.0 | 5 votes |
package cats.scalatest import org.scalatest.matchers.{BeMatcher, MatchResult, Matcher} import scala.util.Either import cats.syntax.either._ trait EitherMatchers { final object EitherMatchers extends EitherMatchers final private[scalatest] class BeCatsRightEitherMatcher[T](element: T) extends Matcher[_ Either T] { def apply(either: _ Either T): MatchResult = MatchResult( either.fold(_ => false, _ == element), s"'$either' did not contain an Right element matching '$element'.", s"'$either' contained an Right element matching '$element', but should not have." ) } final private[scalatest] class BeCatsLeftEither[E](element: E) extends Matcher[E Either _] { def apply(either: E Either _): MatchResult = MatchResult( either.fold(_ == element, _ => false), s"'$either' did not contain an Left element matching '$element'.", s"'$either' contained an Left element matching '$element', but should not have." ) } final private[scalatest] class IsCatsLeftEitherMatcher[E] extends BeMatcher[E Either _] { def apply(either: E Either _): MatchResult = MatchResult( either.isLeft, s"'$either' was not an Left, but should have been.", s"'$either' was an Left, but should *NOT* have been." ) } final private[scalatest] class IsCatsRightEitherMatcher[T] extends BeMatcher[_ Either T] { def apply(either: _ Either T): MatchResult = MatchResult( either.isRight, s"'$either' was not an Right, but should have been.", s"'$either' was an Right, but should *NOT* have been." ) }
Example 8
Source File: EitherValuesSpec.scala From cats-scalatest with Apache License 2.0 | 5 votes |
package cats.scalatest import org.scalatest.exceptions.TestFailedException import scala.util.{Either, Left, Right} class EitherValuesSpec extends TestBase { import EitherValues._ "value on Either" should { "return the value inside a Right if that Either is Right" in { val r: String Either String = Right(thisRecord) r.value should ===(thisRecord) } "should throw TestFailedException if that Either is a left " in { val r: String Either String = Left(thisTobacconist) val caught = intercept[TestFailedException] { r.value should ===(thisRecord) } if (isJVM) caught.failedCodeLineNumber.value should equal(thisLineNumber - 3) caught.failedCodeFileName.value should be("EitherValuesSpec.scala") } } "leftValue on Either" should { "return the value if it's left" in { val r = Left(thisRecord) r.leftValue should ===(thisRecord) } "throw TestFailedException if the Either is right" in { val r = Right(thisRecord) val caught = intercept[TestFailedException] { r.leftValue } if (isJVM) caught.failedCodeLineNumber.value should equal(thisLineNumber - 3) caught.failedCodeFileName.value should be("EitherValuesSpec.scala") } } }
Example 9
Source File: Fire.scala From tofu with Apache License 2.0 | 5 votes |
package tofu import cats.effect.{Concurrent, Fiber} import simulacrum.typeclass import tofu.internal.NonTofu import scala.util.Either import scala.annotation.nowarn @typeclass trait Fire[F[_]] { def fireAndForget[A](fa: F[A]): F[Unit] } object Fire extends StartInstances[Fire] @typeclass trait Race[F[_]] extends Fire[F] { def race[A, B](fa: F[A], fb: F[B]): F[Either[A, B]] def never[A]: F[A] } object Race extends StartInstances[Race] @typeclass trait Start[F[_]] extends Fire[F] with Race[F] { def start[A](fa: F[A]): F[Fiber[F, A]] def racePair[A, B](fa: F[A], fb: F[B]): F[Either[(A, Fiber[F, B]), (Fiber[F, A], B)]] } object Start extends StartInstances[Start] trait StartInstances[TC[f[_]] >: Start[f]] { final implicit def concurrentInstance[F[_]](implicit F: Concurrent[F], @nowarn _nonTofu: NonTofu[F]): TC[F] = new Start[F] { def start[A](fa: F[A]): F[Fiber[F, A]] = F.start(fa) def fireAndForget[A](fa: F[A]): F[Unit] = F.void(start(fa)) def racePair[A, B](fa: F[A], fb: F[B]): F[Either[(A, Fiber[F, B]), (Fiber[F, A], B)]] = F.racePair(fa, fb) def race[A, B](fa: F[A], fb: F[B]): F[Either[A, B]] = F.race(fa, fb) def never[A]: F[A] = F.never } }
Example 10
Source File: DefaultRepositories.scala From cosmos with Apache License 2.0 | 5 votes |
package com.mesosphere.cosmos.repository import com.google.common.io.CharStreams import com.mesosphere.cosmos.rpc import com.twitter.util.Try import io.circe.jawn.decode import java.io.InputStreamReader import scala.util.Either import scala.util.Left import scala.util.Right private[repository] class DefaultRepositories private[repository](resourceName: String) { private val repos: Try[Either[io.circe.Error, List[rpc.v1.model.PackageRepository]]] = Try { Option(this.getClass.getResourceAsStream(resourceName)) match { case Some(is) => val json = CharStreams.toString(new InputStreamReader(is)) decode[List[rpc.v1.model.PackageRepository]](json) case _ => throw new IllegalStateException(s"Unable to load classpath resource: $resourceName") } } } object DefaultRepositories { private[this] val loaded = new DefaultRepositories("/default-repositories.json") def apply(): DefaultRepositories = loaded implicit class DefaultRepositoriesOps(val dr: DefaultRepositories) extends AnyVal { def get(): Try[Either[io.circe.Error, List[rpc.v1.model.PackageRepository]]] = { dr.repos } def getOrThrow: List[rpc.v1.model.PackageRepository] = { get().map { case Right(list) => list case Left(err) => throw err }.get } def getOrElse( orElse: List[rpc.v1.model.PackageRepository] ): List[rpc.v1.model.PackageRepository] = { get().map(_.getOrElse(orElse)).getOrElse(orElse) } } }
Example 11
Source File: AsyncLaws.scala From cats-effect with Apache License 2.0 | 5 votes |
package cats package effect package laws import cats.effect.ExitCase.{Completed, Error} import cats.effect.concurrent.Deferred import cats.implicits._ import cats.laws._ import scala.util.Either trait AsyncLaws[F[_]] extends SyncLaws[F] { implicit def F: Async[F] def asyncRightIsPure[A](a: A) = F.async[A](_(Right(a))) <-> F.pure(a) def asyncLeftIsRaiseError[A](e: Throwable) = F.async[A](_(Left(e))) <-> F.raiseError(e) def repeatedAsyncEvaluationNotMemoized[A](a: A, f: A => A) = F.suspend { var cur = a val change: F[Unit] = F.async { cb => cur = f(cur) cb(Right(())) } val read: F[A] = F.delay(cur) change *> change *> read } <-> F.pure(f(f(a))) def repeatedAsyncFEvaluationNotMemoized[A](a: A, f: A => A) = F.suspend { var cur = a val change: F[Unit] = F.asyncF { cb => cur = f(cur) F.delay(cb(Right(()))) } val read: F[A] = F.delay(cur) change *> change *> read } <-> F.pure(f(f(a))) def repeatedCallbackIgnored[A](a: A, f: A => A) = F.suspend { var cur = a val change = F.delay { cur = f(cur) } val readResult = F.delay(cur) val double: F[Unit] = F.async { cb => cb(Right(())) cb(Right(())) } double *> change *> readResult } <-> F.delay(f(a)) def propagateErrorsThroughBindAsync[A](t: Throwable) = { val fa = F.attempt(F.async[A](_(Left(t))).flatMap(x => F.pure(x))) fa <-> F.pure(Left(t)) } def neverIsDerivedFromAsync[A] = F.never[A] <-> F.async[A](_ => ()) def asyncCanBeDerivedFromAsyncF[A](k: (Either[Throwable, A] => Unit) => Unit) = F.async(k) <-> F.asyncF(cb => F.delay(k(cb))) def bracketReleaseIsCalledOnCompletedOrError[A, B](fa: F[A], b: B) = { val lh = Deferred.uncancelable[F, B].flatMap { promise => val br = F.bracketCase(F.delay(promise)) { _ => fa } { case (r, Completed | Error(_)) => r.complete(b) case _ => F.unit } // Start and forget // we attempt br because even if fa fails, we expect the release function // to run and set the promise. F.asyncF[Unit](cb => F.delay(cb(Right(()))) *> br.attempt.as(())) *> promise.get } lh <-> F.pure(b) } } object AsyncLaws { def apply[F[_]](implicit F0: Async[F]): AsyncLaws[F] = new AsyncLaws[F] { val F = F0 } }
Example 12
Source File: LTask.scala From cats-effect with Apache License 2.0 | 5 votes |
package cats.effect import cats.Eq import cats.effect.internals.Conversions import cats.effect.laws.util.TestContext import org.scalacheck.{Arbitrary, Cogen} import cats.syntax.flatMap._ import cats.syntax.functor._ import scala.concurrent.{ExecutionContext, ExecutionException, Future, Promise} import scala.util.{Either, Left, Right} implicit def effectInstance(implicit ec: ExecutionContext): Effect[LTask] = new Effect[LTask] { def pure[A](x: A): LTask[A] = LTask(_ => Future.successful(x)) def raiseError[A](e: Throwable): LTask[A] = LTask(_ => Future.failed(e)) def suspend[A](thunk: => LTask[A]): LTask[A] = LTask { implicit ec => Future.successful(()).flatMap(_ => thunk.run(ec)) } def async[A](k: (Either[Throwable, A] => Unit) => Unit): LTask[A] = LTask { _ => val p = Promise[A]() k(r => p.tryComplete(Conversions.toTry(r))) p.future } def asyncF[A](k: (Either[Throwable, A] => Unit) => LTask[Unit]): LTask[A] = LTask { implicit ec => val p = Promise[A]() k(r => p.tryComplete(Conversions.toTry(r))).run(ec) p.future } def runAsync[A](fa: LTask[A])(cb: Either[Throwable, A] => IO[Unit]): SyncIO[Unit] = SyncIO(fa.run(ec).onComplete { r => cb(Conversions.toEither(r)).unsafeRunAsyncAndForget() }) def flatMap[A, B](fa: LTask[A])(f: A => LTask[B]): LTask[B] = LTask { implicit ec => Future.successful(()).flatMap { _ => fa.run(ec).flatMap { a => f(a).run(ec) } } } def tailRecM[A, B](a: A)(f: A => LTask[Either[A, B]]): LTask[B] = flatMap(f(a)) { case Left(a) => tailRecM(a)(f) case Right(b) => pure(b) } def handleErrorWith[A](fa: LTask[A])(f: Throwable => LTask[A]): LTask[A] = LTask { implicit ec => Future.successful(()).flatMap { _ => fa.run(ec).recoverWith { case err: ExecutionException if err.getCause ne null => f(err.getCause).run(ec) case err => f(err).run(ec) } } } def bracketCase[A, B]( acquire: LTask[A] )(use: A => LTask[B])(release: (A, ExitCase[Throwable]) => LTask[Unit]): LTask[B] = for { a <- acquire etb <- attempt(use(a)) _ <- release(a, etb match { case Left(e) => ExitCase.error[Throwable](e) case Right(_) => ExitCase.complete }) b <- rethrow(pure(etb)) } yield b } }
Example 13
Source File: Effect.scala From cats-effect with Apache License 2.0 | 5 votes |
package cats package effect import simulacrum._ import cats.data.{EitherT, WriterT} import scala.annotation.implicitNotFound import scala.util.Either implicit def catsWriterTEffect[F[_]: Effect, L: Monoid]: Effect[WriterT[F, L, *]] = new WriterTEffect[F, L] { def F = Effect[F]; def L = Monoid[L] } private[effect] trait EitherTEffect[F[_]] extends Effect[EitherT[F, Throwable, *]] with Async.EitherTAsync[F, Throwable] { protected def F: Effect[F] def runAsync[A](fa: EitherT[F, Throwable, A])(cb: Either[Throwable, A] => IO[Unit]): SyncIO[Unit] = F.runAsync(fa.value)(cb.compose(_.flatMap(x => x))) override def toIO[A](fa: EitherT[F, Throwable, A]): IO[A] = F.toIO(F.rethrow(fa.value)) } private[effect] trait WriterTEffect[F[_], L] extends Effect[WriterT[F, L, *]] with Async.WriterTAsync[F, L] { protected def F: Effect[F] protected def L: Monoid[L] def runAsync[A](fa: WriterT[F, L, A])(cb: Either[Throwable, A] => IO[Unit]): SyncIO[Unit] = F.runAsync(fa.run)(cb.compose(_.map(_._2))) override def toIO[A](fa: WriterT[F, L, A]): IO[A] = F.toIO(fa.value(F)) } }
Example 14
Source File: CancelableF.scala From cats-effect with Apache License 2.0 | 5 votes |
package cats.effect package internals import java.util.concurrent.atomic.AtomicReference import scala.util.Either private[effect] object CancelableF { def apply[F[_], A](k: (Either[Throwable, A] => Unit) => F[CancelToken[F]])(implicit F: Concurrent[F]): F[A] = F.asyncF { cb => val state = new AtomicReference[Either[Throwable, Unit] => Unit](null) val cb1 = (a: Either[Throwable, A]) => { try { cb(a) } finally { // This CAS can only succeed in case the operation is already finished // and no cancellation token was installed yet if (!state.compareAndSet(null, Callback.dummy1)) { val cb2 = state.get() state.lazySet(null) cb2(Callback.rightUnit) } } } // Until we've got a cancellation token, the task needs to be evaluated // uninterruptedly, otherwise risking a leak, hence the bracket F.bracketCase(k(cb1)) { _ => F.async[Unit] { cb => if (!state.compareAndSet(null, cb)) { cb(Callback.rightUnit) } } } { (token, e) => e match { case ExitCase.Canceled => token case _ => F.unit } } } }
Example 15
Source File: ManualWriterMonad.scala From advanced-scala-code with Apache License 2.0 | 5 votes |
package manual import cats.Monad import scala.util.Either case class Writer[V](run: (List[String], V)) { def bind[B](f: V => Writer[B]): Writer[B] = { val (log, value) = run val (nLog, nValue) = f(value).run Writer((log ++ nLog, nValue)) } def bindNaive[B](f: V => Writer[B]): Writer[B] = { val (log, value) = run f(value) } } object ManualWriterMonad { def main(args: Array[String]) { implicit val writerMonad = new Monad[Writer] { override def pure[A](x: A): Writer[A] = Writer((List(), x)) override def flatMap[A, B](fa: Writer[A])(f: (A) => Writer[B]): Writer[B] = fa.bind(f) // Not stack-safe override def tailRecM[A, B](a: A)(f: (A) => Writer[Either[A, B]]): Writer[B] = flatMap(f(a)) { case Right(b) => pure(b) case Left(nextA) => tailRecM(nextA)(f) } } def greetW(name: String, logged: Boolean) = Writer(List("Composing a greeting"), { val userName = if (logged) name else "User" s"Hello $userName" }) def isLoggedW(name: String) = Writer(List("Checking if user is logged in"), name.length == 3) val name = "Joe" import cats.syntax.flatMap._ import cats.syntax.functor._ val resultW = for { logged <- isLoggedW(name) greeting <- greetW(name, logged) } yield greeting val (log, result) = resultW.run println(log) println(result) } }