Comments

We all know that scala futures are a monad… but could we wrap them using scalaz Monad trait? Being able to do that would allow use all scalaz abstractions with our loved scala futures.

It turns out to be a really easy task…

1
2
3
4
5
6
7
  implicit val futureMonad = new Monad[Future] {
    override def point[A](a: => A): Future[A] =
      future(a)

    override def bind[A, B](fa: Future[A])(f: A => Future[B]): Future[B] =
      fa.flatMap(f)
  }

Now we can do lot of fancy things as using the sequence method over a list of Monads, either implementing our own function or bringing some more implicit scalaz magic into place:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package futuremonad

import scala.language.{ higherKinds, postfixOps }

import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.collection.immutable._

import scalaz._
import scalaz.std.list._
import scalaz.syntax.monad._
import scalaz.syntax.traverse._

object Monads extends App {

  implicit val futureMonad = new Monad[Future] {
    override def point[A](a: => A): Future[A] =
      future(a)

    override def bind[A, B](fa: Future[A])(f: A => Future[B]): Future[B] =
      fa.flatMap(f)
  }

  def sequence[T, M[+_] : Monad](l: List[M[T]]): M[List[T]] =
    implicitly[Monad[M]].sequence(l)

  val nums = (1 to 100) toStream
  val even = nums filter (_ % 2 == 0) toList
  val odds = nums filter (_ % 2 == 1) toList

  val fls1 = sequence(even map (a => future(a))) map (_.sum)
  val fls2 = odds.map(a => future(a*2)).sequence map (_.sum)

  fls1 onSuccess {
    case total => println(s"Sum of evens: $total")
  }

  fls2 onSuccess {
    case total => println(s"Sum of 2*odds: $total")
  }

  Await.ready(fls1, 5 seconds)
  Await.ready(fls2, 5 seconds)
}

The source code is available at https://github.com/lvicentesanchez.

Comments

This is going to be a hotchpotch of lot of things related to functional programming and web development. I will focus on:

  • Scala 2.10.+
  • Play 2.1.+ & Akka 2.1.+
  • Scalaz 7.+
  • Shapeless 1.2.+
  • Spire 0.+

Stay tunned!