在ZIO中,有没有办法将IO [Nothing,T]转换为T,如果没有,为什么不呢?

问题描述 投票:0回答:3

在考虑错误并将IO[E, T]转换为IO[Nothing, T]后,我们可以直接将该值称为T类型而不是IO[Nothing, T]。这允许我们返回T类型的值,而不需要使用varIO.map。有没有办法做到这一点,如果没有,为什么不呢?

目前在ZIO的README中找不到解决方案。

scala scalaz
3个回答
4
投票

IO[E, T]只是一个程序的描述,可以返回错误E或产生值T

要实际生成此值,您需要运行此程序。

ZIO设计鼓励将不纯的副作用推到程序的最边缘,即main函数。事实上,你不需要在你的代码中的任何地方显式调用unsafeRun,因为ZIO的App特性可以为你解决这个问题。

话虽这么说,如果你仍然需要这样做,比如因为你还没准备好重构你的整个应用程序,你可以使用RTS特性(RTS代表运行时系统)。

import scalaz.zio._

class SomeService extends RTS {

  val pureProgram: IO[Nothing, String] = ???

  // will throw if pureProgram returns error branch
  def impureMethod: String {
    println("Part of my program is pure, but not all of it")
    unsafeRun(pureProgram)
  }
}

有关其他运行方法,请参阅ZIO RTS Scaladoc


3
投票

没有办法实现一个接受IO[Nothing, T]并返回T的纯函数。

之所以如此,是因为ZIO的IO[_, _]的第一个类型参数描述了在IO包装计算中可能发生的错误。 IO[Nothing, T]描述了一个不会失败的计算,但它仍然封装了一个有效的计算。这就是为什么你不能在纯函数中得到T之类的值。

刚谈到物理可能性,因为Scala不是纯语言,你有可能编写一个接受IO[Nothing, T]并返回T的函数,但你真的不鼓励通过ZIO的设计和意识形态来做到这一点。


3
投票

对于所有在2019年寻找答案的人来说 - API的变化很小。

import scalaz.zio._

object RTS extends DefaultRuntime

class Service {
  val program: UIO[String] = ???

  def mixPureImpure: String = {
    println("Calling service")
    RTS.unsafeRun(program)
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.