Scala Task return mapping

时光怂恿深爱的人放手 提交于 2019-12-24 06:31:12

问题


I have a method readHeader which takes one argument and returns Task[List[Header]] and another method calls for multiple ids and returns List[Task[List[EquipmentHeader]]]. How to make a return of Task[List[List[Header]]] compatible with multiple id read function.

trait M1{
  def readHeader(id: String): Task[List[Header]]
}

def read(ids: List[String])(implicit m1:M1):Task[List[List[Header]]] = {
    if (ids.isEmpty) {
      Task(List.empty)
    } else {
         ids.map(m1.readHeader(_)) //List[Task[List[Header]]]
    }
  }

回答1:


You can use traverse from cats:

import cats.implicits._

ids.traverse(m1.readHeader) // Task[List[List[Header]]]



回答2:


Here is a naive implementation of traverse for just Task and List.
But again, I insist, there is no reason for not using the one defined in cats.

def traverse[A, B](list: List[A])(f: A => Task[B]): Task[List[B]] = {
  @annotation.tailrec
  def loop(remaining: List[A], acc: Task[List[B]]): Task[List[B]] =
    remaining match {
      case a :: as =>
        loop(
          remaining = as,
          acc = for {
            b <- f(a)
            bs <- acc
          } yield b :: bs
        )

      case Nil =>
        acc.map(_.reverse)
    }
  loop(remaining = list, acc = Task.pure(List.empty))
}


来源:https://stackoverflow.com/questions/59397143/scala-task-return-mapping

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!