6

根据cats官方文档:https : //typelevel.org/cats-effect/typeclasses/liftio.html ,如果我们想从IO提升一些东西到其他容器,你应该实现LiftIO trait,但是示例显式运行unsafeRunXXX方法来获取出了效果,我想知道这是转型的唯一途径吗?

4

1 回答 1

5

IO正在暂停副作用,它的类型告诉你如果你运行所有计算(副作用和纯),你会得到什么值,如果最后不会抛出错误(它们可以一路处理)。

因此,不运行计算就不可能获得该值。所以,基本上任何有用的从IO[A]to 的翻译F[A] 都必须在某个地方调用一些.unsafeXXX。该unsafe部分并不意味着您不应该使用它 - 这意味着您需要知道您在运行它时正在做什么,返回的结果将产生副作用,可能会失败并且通常您会放弃关于参考透明度。

这就是为什么它在内部使用它的原因IOApp(它在世界尽头使用它,你想要计算你的结果)。如果你知道这一点,你也可以在不失去参考透明度的情况下翻译IO成另一个:FF

  • 是懒惰的,就像IO一样,
  • 允许暂停副作用,就像 IO 一样,
  • 处理错误,就像 IO 一样。

所以基本上,它是相同概念的另一种实现 - 参见:SyncIO, Coeval, Task, ZIO ...

// example: Async can be used to translate IO into F
def IO2F[F[_]: Async]: IO ~> F = new (IO ~> F) {
  def apply[A](ioa: IO[A]): F[A] = Async[F].async(ioa.unsafeRunAsync)
}

您也可以执行IO[A] => Either[Throwable, A]or之类的操作IO[A] => Option[A],或者IO[A] => Future[A]但您必须记住,每次运行此类评估时,您都会立即开始产生副作用。

长话短说:你想翻译IO成别的东西,你必须在.unsafeXXX某个地方使用一些,这还不错,unsafe只是提醒你必须小心,就是这样。

于 2019-09-14T11:28:01.607 回答