4

Older version of the API was looked something like this (credit to @travisbrown for suggesting traverseU solution here). Note that these two APIs are created as a toy example to illustrate the point on this SO question. Real code is doing more interesting things.

def anotherFunc: Throwable \/ List[String] = personList.flatMap { pl =>
  pl.traverseU { p =>
  for {
    s <- Option("fakeString").\/>(new Throwable("not found"))
  } yield s
 }
}

where

case class Person(name: String)

 private def personList: \/[Throwable, List[Person]] = {
   \/.fromTryCatch {
      List(Person("John"))
  }
}

Now converting this def to Future based will look like as follow

def anotherFunc: Future[Throwable \/ List[String]] = Future {
personList.flatMap { pl =>
  pl.traverseU { p =>
    for {
      s <- Option("fakeString").\/>(new Throwable("not found"))


    } yield s
  }
 }
}

Now as mentioned before this is a toy example but I have a one or more generators in that for comprehension which return disjunction wrapped in Future e.g. Future[\/[Throwable,String]]

you can imagine something like s1 below

   for {
       s <- Option("fakeString").\/>(new Throwable("not found"))
       //s1 <- Future{"returning Future[\/[Throwable,String]" }
   } yield //value out of s1 future must be yielded

Is monad transformation needed here?

e.g. To get value of out Future monad (s1 in this case) and transform to appropriately to match with the return of anotherFunc ? not sure if EitherT can help here?

Update

Simplifying the example. This is what anotherFunc looks like with one of the generators returning Future[\/[Throwable,String]]. Basically want to avoid using Await

def anotherFunc: Future[Throwable \/ List[String]] = Future {
personList.flatMap { pl =>
  pl.traverseU { p =>
    for {
      s <- Option("fakeString").\/>(new Throwable("not found"))
      f <- Await.result(futureResult, 1.seconds)
    } yield f
  }
}
}

def futureResult = Future{Option("""another Disjunction is called here - which returns a    Future[\/[Throwable,T]""").\/>(new Throwable("not found"))}
Community
  • 1
  • 1
Vikas Pandya
  • 1,998
  • 1
  • 15
  • 32
  • 3
    Monad transformers are never _necessary_, really, but they can make this kind of operation much more convenient—see my answer [here](http://stackoverflow.com/a/21993273/334519) for a very similar example. – Travis Brown Jun 23 '14 at 16:16
  • @TravisBrown : Thanks. I did see that post but if the `func` is already wrapped in a `Future`,as shown in the post above,where `anotherFunc` is wrapped in `Future{}` and all other generators in there return disjunctions except this one which returns `Future[\/[Throwable,String]]` how to still align types in `for` comprehension and still satisfy `anotherFunc` return type which is `Future[Throwable \/ List[String]]` – Vikas Pandya Jun 23 '14 at 18:28
  • @TravisBrown : Added an example in `Update` section to illustrate the problem. Thanks. – Vikas Pandya Jun 23 '14 at 22:30

0 Answers0