paul
paul

Reputation: 13471

Monad transformer flatMap working

I´ve been playing monad transformer, and I just create one Future[Option]. But after read some blogs there´s something that is not explained and I don't understand.

Here in the implementation of my map and flatMap, in the flatMap once that I get the value of my option, and I apply the function over the value, I have to invoke over the function f(a) the .Value_passed_in_the_case_class(in this case future)

case class FutOpt[A](future: Future[Option[A]]) {

def map[B](f: A => B): FutOpt[B] = {
  FutOpt(future.map(option => option.map(value => f(value)))
    .recoverWith {
      case e: Exception =>
        Future.successful(Option.empty)
    })
}

def flatMap[B](f: A => FutOpt[B]): FutOpt[B] =
  FutOpt(future.flatMap(option => option match {
    case Some(a) => f(a).future  --> WHAT THIS .future IS DOING?
    case None => Future.successful(None)
  }))
}

What is happening there?, and how works?.

Regards.

Upvotes: 2

Views: 154

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

What is happening there?

flatMap expects you to return it a FutOpt[B]:

def flatMap[B](f: A => FutOpt[B]): FutOpt[B]

The signature of your case class requires you to pass in a Future[Option[A]]:

case class FutOpt[A](future: Future[Option[A]])

This line of code:

FutOpt(future.flatMap(option => option match {
    case Some(a) => f(a).future

Is constructing a new instance of FutOpt[B], and it needs a value of type Future[Option[B]] in order to be able to construct itself properly. f(a) returns a FutOpt[B], not a Future[Option[B]], and that is why it needs to access .future, which is of type Future[Option[B]].

Upvotes: 1

Related Questions