Skip to content

Instantly share code, notes, and snippets.

@banshee
Created December 10, 2013 07:15
Show Gist options
  • Save banshee/7886842 to your computer and use it in GitHub Desktop.
Save banshee/7886842 to your computer and use it in GitHub Desktop.
Talk for Seattle Scala group
package com.restphone
import scalaz._
import Scalaz._
import scala.concurrent.Future
import scala.concurrent.Future._
import scala.concurrent.Await
import scala.concurrent.duration._
object MonadEvidenceThatWillMakeSenseLater {
import scala.concurrent.ExecutionContext.Implicits.global
// To use EitherT with a scala.concurrent.Future, we need to
// provide evidence that scala.concurrent.Future is a scalaz.Monad
implicit val convertScalaFutureToScalazMonad = new Monad[Future] {
def point[A](a: => A): Future[A] = Future { a }
def bind[A, B](fa: Future[A])(f: A => Future[B]): Future[B] = fa.flatMap(f)
}
}
object SimplifyErrorHandlingWithEitherT extends App {
import scala.concurrent.ExecutionContext.Implicits.global
import MonadEvidenceThatWillMakeSenseLater._
type ProgramError = String // You'll have real types; this just makes the sample easier to read
// Working with Future[ProgramError \/ String] isn't straightforward
def workWithFutureOfProgramErrorOrString(input: Future[ProgramError \/ String]) = for {
x <- input // x is ProgramError \/ String; not quite what we want
lengthOfString = ???
} yield 42
def workDirectlyWithString(inputs: Future[ProgramError \/ String]) = for {
x <- EitherT(inputs) // notice the type of x is string, so we don't have to look at future or the error
lengthOfString = x.length
} yield lengthOfString
def useEitherTToSimplify(input: Future[ProgramError \/ String]): EitherT[Future, ProgramError, Int] = for {
x <- EitherT(input)
lengthOfString = x.length
} yield lengthOfString
// Use operations like fold to get a count ignoring errors.
val result = useEitherTToSimplify(Future { "abc".right }).fold(_ => 0, identity)
result.onComplete {
x => println(s"result is: $x")
}
val result2 = useEitherTToSimplify(Future { "BOOM!".left }).fold(_ => 0, identity)
result2.onComplete {
x => println(s"result is: $x")
}
Thread.sleep(2000)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment