我在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>
答案 0 :(得分:2)
fold
(link)中的方法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)
上面的代码打印出“成功res = 6”。
答案 1 :(得分:1)
从本质上讲,使用ZIO进行的所有操作(包括collectAll
和fold
都是对函数的操作,因为每个ZIO本质上都是异想天开的函数。在您的情况下,ZIO[Console, Throwable, List[Int]]
是一个函数,其中Console
是输入参数,而Throwable
/ List[Int]
是两种可能的输出类型之一。当使用collectAll
和fold
之类的组合器时,您基本上会基于其他函数构造一个新函数。
下一步是通过将输入参数传递给新函数来评估它。在您的情况下,此输入参数是扩展Console
类型的任何特征。正如@slouc在他的回答中反映的那样,您只能在DefaultRuntime
上使用res0
“ runner”,因为此运行器提供的默认环境(根据功能输入参数)实现了Console
特性。
import zio.DefaultRuntime
val runtime = new DefaultRuntime {}
runtime.unsafeRun(res0)
还有另一种更明确的方法,可以使用ZIO#provide提供此Env,但是此后您仍然需要一些运行时才能执行此功能。
我还想指出,当您在println
内进行fold
时,实际上并没有使用提供的Console
特征作为输入参数,而是使用常规的{ {1}}由本机Scala提供。在您的基本情况下,这无关紧要,但是在实际应用程序中,您将需要使用println
提供的putStrLn
。