3
votes

Consider the following code which uses ScalaZ's OptionT:

val answer = for {
      customer <- optionT(function1(codeString))
      customerId <- someOptionT(Future(Seq(function2(customer)))
      alerts <- someOptionT(Future.sequence(function3(customerId))
} yield alerts
  • function1 returns Future[Option[Customer]]
  • function2 returns String
  • function3 returns Seq[Future[Option[String]]]

Meanwhile this is someOptionT

def someOptionT[T](t: Future[T]): OptionT[Future, T] = optionT[Future](t.map(Some.apply))

I get the following exception on the last line of the for comprehension (with alerts):

could not find implicit value for parameter F: scalaz.Functor[scala.concurrent.Future]

Any idea as to why?

1

1 Answers

8
votes

The error message is totally unclear, but the problem is exactly the same as if you wrote myFuture.map(whatever) in the REPL without an implicit execution context in scope.

scala> import scala.concurrent.Future
import scala.concurrent.Future

scala> def foo(myFuture: Future[Int]) = myFuture.map(_ + 1)
<console>:8: error: Cannot find an implicit ExecutionContext. You might pass
an (implicit ec: ExecutionContext) parameter to your method
or import scala.concurrent.ExecutionContext.Implicits.global.
       def foo(myFuture: Future[Int]) = myFuture.map(_ + 1)
                                                    ^

Scalaz provides a Functor (and a Monad, etc.) for Future, but you have to have an execution context around to get them. Import global (or provide one some other way) and you'll be fine.