从 Task[Either[A, Task[B]]] 转换为 Task[Either[A, B]]

Converting from Task[Either[A, Task[B]]] to Task[Either[A, B]]

我正在使用 monix 来处理副作用并以这种类型结束

Task[Either[A, Task[B]]],有没有办法得到Task[Either[A, B]]?

到目前为止,我所能做的就是将 Task[Either[A, Task[B]]] 转换为 Task[Any],基本上是使用模式匹配和展平来删除 Either,但在过程中缺少类型信息

val tEitherT: Task[Either[A, Task[B]]] = ???

val finalType: Task[Any] = 
tEitherT.map(either => {
  either match {
   case Right(value) => value      // Task[B]
   case Left(value) => Task(value) // Lift    
}  
}).flatten

试试这个:

tEitherT.flatMap {
  case Right(taskB) => taskB.map(Right(_))
  case Left(a) => Task(Left(a))
}

Try it out!

import monix.eval.Task
import cats.implicits._
import cats.Traverse

trait A
trait B

def tEitherT: Task[Either[A, Task[B]]] = ???

type EitherRight[T] = Either[A,T] // or use kind-projector plugin instead

val finalType: Task[Either[A, B]] = 
   tEitherT.flatMap(Traverse[EitherRight].sequence(_))

在 scala 2.13 中或使用选项 -Ypartial-unification,您可以简化为 tEitherT.flatMap(_.sequence)。见第二个答案 .