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 vote down vote up
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 vote down vote up
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
Source File: var.scala    From catbird   with Apache License 2.0 5 votes vote down vote up
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
Source File: try.scala    From catbird   with Apache License 2.0 5 votes vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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)
  }
}