Skip to content

Instantly share code, notes, and snippets.

@x7c1
Last active August 29, 2015 14:05
Show Gist options
  • Select an option

  • Save x7c1/e159af5ff7d27741dde8 to your computer and use it in GitHub Desktop.

Select an option

Save x7c1/e159af5ff7d27741dde8 to your computer and use it in GitHub Desktop.
sample to put F[ \/[...] ] in for-yield and convert from F[E1 \/ A] to F[E2 \/ A]
import scala.language.higherKinds
import scalaz.{Functor, \/}
class LeftConverter[E1, E2](g: E1 => E2) {
def apply[A, F[_]](f: F[E1 \/ A])(implicit F: Functor[F]): F[E2 \/ A] =
F.map(f)(_.leftMap(g))
}
object LeftConverter {
def apply[E1, E2](g: E1 => E2): LeftConverter[E1, E2] = new LeftConverter(g)
}
LeftConverter.getClass.getSimpleName should {
import scalaz.EitherT.eitherT
import scalaz.{Monad, \/}
class SampleError
class SampleArgumentError extends SampleError
class SampleOperationError extends SampleError
val convert = LeftConverter[Exception, SampleError]{
case e: IllegalArgumentException => new SampleArgumentError
case e: UnsupportedOperationException => new SampleOperationError
}
"""convert left type of Future[\/[...]]""" in {
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import scala.concurrent.Future
implicit def futureMonad = new Monad[Future] {
override def point[A](a: => A) = Future(a)
override def bind[A, B](fa: Future[A])(f: A => Future[B]) = fa flatMap f
}
def execute(f: Future[SampleError \/ Int]) = Await.result(f, Duration.Inf).toEither
type Test = Int => Future[Exception \/ Int]
val f1: Test = x => Future(\/ right 100 + x)
val f2: Test = x => Future(\/ right 200 + x)
val f3: Test = x => Future(\/ left new IllegalArgumentException)
val f4: Test = x => Future(\/ left new UnsupportedOperationException)
val y1 = for {
a1 <- eitherT(convert apply f1(10))
a2 <- eitherT(convert apply f2(a1))
} yield {
a2
}
execute(y1.run).right.get must equalTo(310)
val y2 = for {
a1 <- eitherT(convert apply f1(10))
a2 <- eitherT(convert apply f2(a1))
a3 <- eitherT(convert apply f3(a2))
} yield {
a3
}
execute(y2.run).left.get must beAnInstanceOf[SampleArgumentError]
val y3 = for {
a1 <- eitherT(convert apply f1(10))
a3 <- eitherT(convert apply f3(a1))
a2 <- eitherT(convert apply f2(a3))
a4 <- eitherT(convert apply f4(a2))
} yield {
a4
}
execute(y3.run).left.get must beAnInstanceOf[SampleArgumentError]
}
"""convert left type of Reader[_, \/[...]]""" in {
import scalaz.Reader
type AppliedReader[+Y] = Reader[String, Y]
def execute(f: AppliedReader[SampleError \/ Int]) = f.run("reader-argument").toEither
type Test = Int => AppliedReader[Exception \/ Int]
val f1: Test = x => Reader{ y => \/ right 100 + x }
val f2: Test = x => Reader{ y => \/ right 200 + x }
val f3: Test = x => Reader{ y => \/ left new IllegalArgumentException }
val f4: Test = x => Reader{ y => \/ left new UnsupportedOperationException }
val y1 = for {
a1 <- eitherT(convert apply f1(10))
a2 <- eitherT(convert apply f2(a1))
} yield {
a2
}
execute(y1.run).right.get must equalTo(310)
val y2 = for {
a1 <- eitherT(convert apply f1(10))
a2 <- eitherT(convert apply f2(a1))
a3 <- eitherT(convert apply f3(a2))
} yield {
a3
}
execute(y2.run).left.get must beAnInstanceOf[SampleArgumentError]
val y3 = for {
a1 <- eitherT(convert apply f1(10))
a3 <- eitherT(convert apply f3(a1))
a2 <- eitherT(convert apply f2(a3))
a4 <- eitherT(convert apply f4(a2))
} yield {
a4
}
execute(y3.run).left.get must beAnInstanceOf[SampleArgumentError]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment