Skip to content

Instantly share code, notes, and snippets.

@robinp
Created June 27, 2012 18:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robinp/3005729 to your computer and use it in GitHub Desktop.
Save robinp/3005729 to your computer and use it in GitHub Desktop.
Akka Future Applicative typeclass for scalaz-seven
package akkaz
import akka.actor._
import akka.util.duration._
import akka.util.Timeout
import akka.dispatch.{ExecutionContext, Future}
object Futureapplicative extends App {
val system = ActorSystem("Futureapplicative")
implicit val timeout = Timeout(5 seconds)
implicit val dispatcher = ExecutionContext.defaultExecutionContext(system)
//
// Without scalaz
//
///////// CODE
private def funcReturnEither(x: Int): Either[Exception, Int] = Right(x * 2)
private def funcReturnEither2(x: Int): Either[Exception, Int] = Right(x - 1)
val f1: Future[Either[Exception, Int]] = Future { Right(1) }
val f2: Future[Either[Exception, Int]] = f1 flatMap { maybeX => Future { maybeX.right.flatMap(funcReturnEither) } }
val f3: Future[Either[Exception, Int]] = f2 flatMap { maybeX => Future { maybeX.right.flatMap(funcReturnEither) } }
val f4: Future[Either[Exception, Int]] = f1 flatMap { maybeX => Future { maybeX.right.flatMap(funcReturnEither2) } }
val res: Future[Either[Exception, (Int, Int, Int, Int)]] =
for {
r1 <- f1
r2 <- f2
r3 <- f3
r4 <- f4
} yield {
for {
x <- r1.right
y <- r2.right
z <- r3.right
w <- r4.right
} yield (x, y, z, w)
}
res.foreach(println)
////////// END
//
// With scalaz
//
import scalaz._
import Scalaz._
// Some typeclass for Future
trait FutureFunctor extends Functor[Future] {
override def map[A, B](fa: Future[A])(f: (A) => B) =
fa.map(f)
}
trait FutureApply extends Apply[Future] {
override def ap[A, B](fa: => Future[A])(f: => Future[(A) => B]): Future[B] =
fa.zip(f).map{case (a, f) => f(a)}
}
trait FuturePointed extends Pointed[Future] {
override def point[A](a: => A) = Future { a }
}
object FutureApplicative extends Applicative[Future] with FutureFunctor with FutureApply with FuturePointed
// The composed applicative
implicit val futureValidatedApplicative2: Applicative[({type l[x] = Future[ValidationNEL[Exception, x]]})#l] =
FutureApplicative.compose[({type l[x] = ValidationNEL[Exception, x]})#l]
// some typedefs for convenient usage
type Validated[A] = ValidationNEL[Exception, A]
type FutureValidated[A] = Future[Validated[A]]
//////// CODE
private def funcReturnValidation(x: Int): Validated[Int] = (x * 2).successNel
private def funcReturnValidation2(x: Int): Validated[Int] = (x - 1).successNel
val g1: FutureValidated[Int] = Future { 1.successNel }
val g2: FutureValidated[Int] = g1 flatMap { maybeX => Future { maybeX.flatMap(funcReturnValidation) } }
val g3: FutureValidated[Int] = g2 flatMap { maybeX => Future { maybeX.flatMap(funcReturnValidation) } }
val g4: FutureValidated[Int] = g1 flatMap { maybeX => Future { maybeX.flatMap(funcReturnValidation2) } }
val res2: FutureValidated[(Int, Int, Int, Int)] = (g1 <****> (g2, g3, g4))((_, _, _, _))
res2.foreach(println)
//////// END
// the following doesn't typecheck due to SI-2712
// val y = ((Future(2.successNel[Exception])) |@| Future(22.successNel[Exception]))(_ + _)
// but this passes
// val g1: FutureValidated[Int] = Future(2.successNel)
// val g2: FutureValidated[Int] = Future(3.successNel)
// val x = (g1 |@| g2)(_ + _)
system.shutdown()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment