2

我有一个方法 readHeader ,它接受一个参数并返回Task[List[Header]],另一种方法调用多个 id 并返回List[Task[List[EquipmentHeader]]]。如何使Task[List[List[Header]]]的返回兼容多个 id 读取功能。

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]]]
    }
  }
4

2 回答 2

2

您可以traverse中使用:

import cats.implicits._

ids.traverse(m1.readHeader) // Task[List[List[Header]]]
于 2019-12-18T17:37:57.570 回答
2

这是traversefor和List的简单实现。
但是,我再次坚持,没有理由不使用 cat 中定义的那个

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))
}
于 2019-12-18T18:11:11.627 回答