I am following this. Structure of my program is:
(for {
data <- myService.fetch(id).eitherT
values <- anotherService.fetch(data.id).eitherT
// todo: process values as part of forcomprehension
} yield data.id).value
myService.fetch returns Future[...].
anotherService.fetch also returns Future[...], and values is a Seq. I want to process entries in values using foreach
values.foreach(value => service.moreAction(value))
moreAction also returns Future[...]
Hence my aim is to chain it with previous Futures in for-comprehension itself.
What is idiomatic way of doing it?
CodePudding user response:
In Cats if you want to go through all values of some data, apply some effect to them, and then get a data within this effect:
DataOf[A] => (A => Effect[B]) => Effect[DataOf[B]]
you use Traverse
type class with its extension methods.
(Think of it like of generalization of Future.sequence
which takes Seq[Future[A]]
and returns Future[Seq[A]]
, but one which performs seq.map(toFuture)
and Future.sequence
in one step).
import cats.syntax.traverse._
for {
data <- myService.fetch(id).eitherT
values <- anotherService.fetch(data.id).eitherT
// Traverse is not available for Seq, it requires some specific data e.g. List
result <- values.toList.traverse(value => service.moreAction(value).eitherT)
} yield result