3

How to convert List[Task[List[Header]]] type to Task[List[Header]] in scala .

I have a method which returns Task[List[Header]] and calling dor multiple times it becomes List[Task[List[Header]]]

Luka Jacobowitz
  • 22,795
  • 5
  • 39
  • 57
Sumeet Kumar Yadav
  • 11,912
  • 6
  • 43
  • 80
  • You can easily achieve this with two minor modifications to the answers [here](https://stackoverflow.com/questions/59397143/scala-task-return-mapping) Also, why do you insist in looking for solutions without using **cats**? – Luis Miguel Mejía Suárez Dec 19 '19 at 12:27

2 Answers2

6

You can use Task.sequence, and then map flatten over the resulting list of lists, e.g:

val res: List[Task[List[Header]]] = ...
Task.sequence(res).map(_.flatten)

If you need parallel execution over the results, you can take a look on Task.gather.

mutantacule
  • 6,913
  • 1
  • 25
  • 39
  • How it works can you explain in detail, it is possible to do using case class or foldleft – Sumeet Kumar Yadav Dec 19 '19 at 12:18
  • 1
    Task.sequence, takes a Seq[Task[A]] and returns a Task[Seq[A]], thus transforming any sequence of tasks into a task with a sequence of results and with ordered effects and results. This means that the tasks WILL NOT execute in parallel. Also you can probably: `Task.sequence(res).flatten` – amer Dec 19 '19 at 13:19
4

That use case is covered by the function flatSequence: https://github.com/typelevel/cats/blob/v2.1.0/core/src/main/scala/cats/Traverse.scala#L86

As you can see it takes an F[G[F[A]] and turns it into a G[F[A]]. Now replace F with List and G with Task and you've got what you need. This will work for any F with a Traverse and FlatMap instance and any G with an Applicative instance.

If you want to run the tasks in parallel instead, you can use parFlatSequence found here: https://github.com/typelevel/cats/blob/v2.1.0/core/src/main/scala/cats/Parallel.scala#L155

Luka Jacobowitz
  • 22,795
  • 5
  • 39
  • 57