2

我在 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>
4

2 回答 2

2

( linkfold )中的方法定义为: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”。

于 2019-11-06T21:16:06.397 回答
1

本质上,所有使用 ZIO 的操作包括collectAllfold都是对函数的操作,因为每个 ZIO 本质上基本上都是一个异想天开的函数。在您的情况下ZIO[Console, Throwable, List[Int]]是一个函数,其中Console是一个输入参数,并且Throwable/List[Int]是两种可能的输出类型之一。当您使用类似的组合器时collectAllfold您基本上会基于其他函数构造一个新函数。

下一步是通过将输入参数传递给它来评估这个新函数。在您的情况下,此输入参数是扩展Console类型的任何特征。正如@slouc 在他的回答中所反映的那样,您可以只DefaultRuntime在您res0Console.

import zio.DefaultRuntime

val runtime = new DefaultRuntime {}

runtime.unsafeRun(res0) 

还有另一种更明确的方法是使用 ZIO#provide 来提供这个 Env,但之后你仍然需要一些运行时来执行这个函数。

我还想指出,当你在你println的内部做的时候fold,你实际上并没有使用Console你提供的特征作为输入参数,而是使用println原生 scala 提供的常规。在您的基本情况下,这并不重要,但在实际应用程序中,您需要putStrLn使用Console.

于 2019-11-07T08:29:20.763 回答