Выходное значение типа A как результат - PullRequest
2 голосов
/ 06 ноября 2019

У меня есть следующий код в IDEA (мастерская scala),

import zio.console.Console
import zio.{IO, Task, ZIO}

val st :Seq[Task[Int]] = Seq(Task(1),Task(2),Task(3))

val t : Task[List[Int]]= IO.collectAll(st)

val r : ZIO[Console, Throwable, List[Int]] = t

r.fold(
  f => {
    println(s"fail f=$f");
    0
  },
  s => {
    println(s"success res = ${s.sum}");
    1
  }
)

Не могли бы вы помочь мне с выводом результата (ожидается 6)

У меня есть вывод

st: Seq[zio.Task[Int]] = List(zio.ZIO$EffectPartial@263c8be8, zio.ZIO$EffectPartial@469dccd5, zio.ZIO$EffectPartial@1a56563e)

t: zio.Task[List[Int]] = zio.ZIO$FlatMap@1e8d80f2
r: zio.ZIO[zio.console.Console,Throwable,List[Int]] = zio.ZIO$FlatMap@1e8d80f2

res0: zio.ZIO[zio.console.Console,Nothing,Int] = <function1>

Ответы [ 2 ]

2 голосов
/ 07 ноября 2019

Метод fold в zio.ZIO ( ссылка ) определяется как:

final def fold[B](failure: E => B, success: A => B): ZIO[R, Nothing, B]

Эта подпись показывает, что метод возвращает именно тот тип, который вы получили, zio.ZIO[zio.console.Console, Nothing, Int].

Вы можете запустить эффект в режиме исполнения по умолчанию, например так:

import zio.DefaultRuntime

val runtime = new DefaultRuntime {}

runtime.unsafeRun(effect)

Выше код выводит «success res = 6».

1 голос
/ 07 ноября 2019

По сути, все операции с ZIO, включая collectAll и fold, являются операциями над функциями, поскольку каждый ZIO по своей природе является в основном капризной функцией. В вашем случае ZIO[Console, Throwable, List[Int]] - это функция, где Console является входным параметром, а Throwable / List[Int] является одним из двух возможных типов вывода. Когда вы используете комбинаторы, такие как collectAll и fold, вы в основном создаете новую функцию на основе других функций.

Следующим шагом является оценка этой новой функции путем передачи в нее входного параметра. В вашем случае этим входным параметром является любая черта, которая расширяет тип Console. Как @slouc отразил в своем ответе, вы можете просто использовать DefaultRuntime "runner" на вашем res0, потому что среда по умолчанию (входной параметр в терминах функций), предоставляемая этим бегуном, реализует черту Console.

import zio.DefaultRuntime

val runtime = new DefaultRuntime {}

runtime.unsafeRun(res0) 

Существует еще один более явный способ предоставления этого Env с использованием обеспечения ZIO #, но вам все равно потребуется некоторое время выполнения для выполнения этой функции после этого.

Я также хочу отметить, что когда вы делаете println внутри вашего fold, вы фактически не используете черту Console, которую вы предоставляете в качестве входного параметра, но вы используете обычную println при условиивместо родной скалы. В базовом случае это не имеет значения, но в реальных приложениях вам нужно будет использовать putStrLn, предоставленный Console.

...