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"))}