Преобразование ZIO Task в IO - PullRequest
0 голосов
/ 12 июля 2020

У меня есть следующий код:

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]

Как преобразовать из Задачи (где я звоню method) в IO?

1 Ответ

2 голосов
/ 12 июля 2020

Вам нужно будет решить, что вы хотите делать с 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]

Наконец, если вы хотите, чтобы результат отображался в an Either, вы можете использовать .either, что выведет ошибку из канала ошибок и отобразит ее в Either[E, A]

method(input).either // UIO[Either[Throwable, Boolean]]

. Есть отличная шпаргалка (хотя, по общему признанию, дата) здесь также

...