将 ZIO 任务转换为 IO
Convert ZIO Task to IO
我有下一个代码:
import zio._
import scala.concurrent.Future
case class AppError(description: String) extends Throwable
// legacy-code imitation
def method(x: Int): Task[Boolean] = {
Task.fromFuture { implicit ec => Future.successful(x == 0) }
}
def handler(input: Int): IO[AppError, Int] = {
for {
result <- method(input)
_ <- IO.fail(AppError("app error")).when(result)
} yield input
}
但是这段代码无法编译,因为编译器说结果类型是:
ZIO[Any, Throwable, Int]
如何从 Task(我调用 method
)转换为 IO?
您需要决定要如何处理 Throwable
不是 AppError
.
的错误
如果您决定要将它们映射到 AppError
,您可以这样做:
method(input).mapError {
case ae: AppError => ae
case other => AppError(other.getMessage)
}
如果您想改进这些错误并只保留 AppError
的错误,那么您可以使用 refine*
运算符家族之一,这将保留与谓词匹配的错误并终止纤维否则。
method(input).refineToOrDie[AppError] // IO[AppError, Boolean]
// Or
method(input).refineOrDie { case ae: AppError => ae } // IO[AppError, Boolean]
或者如果您想假设来自 method
的所有错误都被视为“光纤终止”,那么您可以使用 .orDie
吸收错误并终止光纤:
method(input).orDie // UIO[Boolean]
或者,如果您想从错误中恢复并以不同的方式处理它,那么您可以使用 catch*
系列
method(input).catchAll(_ => UIO.succeed(false)) // UIO[Boolean]
最后,如果您想将结果映射到 Either
,您可以使用 .either
,这会将错误从错误通道中移除并将其映射到 Either[E, A]
method(input).either // UIO[Either[Throwable, Boolean]]
有一个很棒的秘籍sheet(虽然有点过时了)here
我有下一个代码:
import zio._
import scala.concurrent.Future
case class AppError(description: String) extends Throwable
// legacy-code imitation
def method(x: Int): Task[Boolean] = {
Task.fromFuture { implicit ec => Future.successful(x == 0) }
}
def handler(input: Int): IO[AppError, Int] = {
for {
result <- method(input)
_ <- IO.fail(AppError("app error")).when(result)
} yield input
}
但是这段代码无法编译,因为编译器说结果类型是:
ZIO[Any, Throwable, Int]
如何从 Task(我调用 method
)转换为 IO?
您需要决定要如何处理 Throwable
不是 AppError
.
如果您决定要将它们映射到 AppError
,您可以这样做:
method(input).mapError {
case ae: AppError => ae
case other => AppError(other.getMessage)
}
如果您想改进这些错误并只保留 AppError
的错误,那么您可以使用 refine*
运算符家族之一,这将保留与谓词匹配的错误并终止纤维否则。
method(input).refineToOrDie[AppError] // IO[AppError, Boolean]
// Or
method(input).refineOrDie { case ae: AppError => ae } // IO[AppError, Boolean]
或者如果您想假设来自 method
的所有错误都被视为“光纤终止”,那么您可以使用 .orDie
吸收错误并终止光纤:
method(input).orDie // UIO[Boolean]
或者,如果您想从错误中恢复并以不同的方式处理它,那么您可以使用 catch*
系列
method(input).catchAll(_ => UIO.succeed(false)) // UIO[Boolean]
最后,如果您想将结果映射到 Either
,您可以使用 .either
,这会将错误从错误通道中移除并将其映射到 Either[E, A]
method(input).either // UIO[Either[Throwable, Boolean]]
有一个很棒的秘籍sheet(虽然有点过时了)here