如何在ZIO中优雅地组合包含多个任务的选项

问题描述 投票:1回答:2

我正在寻找最优雅的实现

import scalaz.zio.Task

def combineTasks[A, B, C, D](task1: Task[Option[A]],
                             task2: Task[Option[B]],
                             task3: Task[Option[C]])
                            (f: (A, B, C) => D)
: Task[Option[D]]

运用

  1. 没有其他依赖项
  2. scalaz-zio-interop-catscats
  3. scalaz-zio-interop-scalaz7xscalaz7x

解决方案应该很好地概括为n个参数。

scala scalaz scala-cats scalaz7 scalaz-zio
2个回答
1
投票

使用cat,您可以使用mapN组合多个选项。这样可行:

import cats._
import cats.implicits._

val o1 = 1.some
val o2 = 2.some
val o3 = 3.some

(o1,o2,o3).mapN((a,b,c) => a |+| b |+| c) // Some(6)

只剩下要做的事情就是解开任务,因为它们是monad,你可以这样做:

for {
  t1 <- task1 
  t2 <- task2 
  t3 <- task3 
} yield (t1,t2,t3)
  .mapN((a,b,c) => /* combine a,b,c */)

1
投票

在得到一些帮助和研究之后,我找到了以下实现,这对我来说似乎是最优雅的:

1.不使用其他依赖项:

def combineTasks[A, B, C, D](task1: Task[Option[A]],
                             task2: Task[Option[B]],
                             task3: Task[Option[C]])
                            (f: (A, B, C) => D)
: Task[Option[D]] = {
  for {
    t1 <- task1
    t2 <- task2
    t3 <- task3
  } yield {
    (t1, t2, t3) match {
      case (Some(t1), Some(t2), Some(t3)) => Some(f(t1, t2, t3))
      case _ => None
    }
  }
}

2.使用scalaz-zio-interop-catscats

def combineTasks[A, B, C, D](task1: Task[Option[A]],
                             task2: Task[Option[B]],
                             task3: Task[Option[C]])
                            (f: (A, B, C) => D)
: Task[Option[D]] = {
  import cats.implicits.catsStdInstancesForOption
  import cats.Apply
  import scalaz.zio.interop.catz._

  Apply[Task].compose[Option].map3(task1, task2, task3)(f)
}

请参阅mapN over composed Apply进行相关讨论。

3.使用scalaz-zio-interop-scalaz7xscalaz7x

def combineTasks[A, B, C, D](task1: Task[Option[A]],
                             task2: Task[Option[B]],
                             task3: Task[Option[C]])
                            (f: (A, B, C) => D): Task[Option[D]] = {
  import scalaz.Apply
  import scalaz.std.option._
  import scalaz.zio.interop.scalaz72._

  Apply[Task].compose[Option].apply3(task1, task2, task3)(f)
}
© www.soinside.com 2019 - 2024. All rights reserved.