根据cats官方文档:https : //typelevel.org/cats-effect/typeclasses/liftio.html ,如果我们想从IO提升一些东西到其他容器,你应该实现LiftIO trait,但是示例显式运行unsafeRunXXX
方法来获取出了效果,我想知道这是转型的唯一途径吗?
问问题
567 次
1 回答
5
IO
正在暂停副作用,它的类型告诉你如果你运行所有计算(副作用和纯),你会得到什么值,如果最后不会抛出错误(它们可以一路处理)。
因此,不运行计算就不可能获得该值。所以,基本上任何有用的从IO[A]
to 的翻译F[A]
都必须在某个地方调用一些.unsafeXXX
。该unsafe
部分并不意味着您不应该使用它 - 这意味着您需要知道您在运行它时正在做什么,返回的结果将产生副作用,可能会失败并且通常您会放弃关于参考透明度。
这就是为什么它在内部使用它的原因IOApp
(它在世界尽头使用它,你想要计算你的结果)。如果你知道这一点,你也可以在不失去参考透明度的情况下翻译IO
成另一个:F
F
- 是懒惰的,就像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 回答