使用 ZIO 在 Scala 中组合多个期货和期权
Composing Multiple Futures and Option in Scala with ZIO
我刚刚开始评估 ZIO 以改进我的异步 Scala 代码的编程模型和性能。在我的代码库中,我经常处理 Future[Option[T]]
,到目前为止,我已经使用 Scalaz 的 OptionT
monad 转换器来处理它。现在我想用 ZIO 试试这个。
考虑两个函数:
def foo: String => Future[Option[T]]
和
def bar: T => Future[U]
我试过这样的事情:
val t = for {
o: Option[Int] <- ZIO.fromFuture { implicit ec =>
foo("test")
}
i: Int <- ZIO.fromOption(o)
s: String <- ZIO.fromFuture { implicit ec =>
bar(i)
}
} yield s
根据我的 IDE,t
在这种情况下属于 ZIO[Any, Any, String]
类型。我不知道该怎么办。
我想考虑三种可能:
- "success" 的情况
foo
产生一个 Some
可以与值 上的其他函数组合
foo
产生 None
的情况
- 任一函数产生错误的情况
我不确定如何使用 ZIO 解析这种情况下的这些可能性。感谢任何帮助。
ZIO.fromOption(o)
is IO[Unit, A]
which is ZIO[Any, Unit, A]
, whilst the type of ZIO.fromFuture
is Task[A]
which is ZIO[Any, Throwable, A]
, as documented by Type Aliases 的类型。因此类型不对齐
ZIO[Any, Unit, A]
ZIO[Any, Throwable, A]
尝试 mapError
将错误类型与 Throwable
对齐,就像这样
for {
o <- ZIO.fromFuture { implicit ec => foo("test") }
i <- ZIO.fromOption(o).mapError(_ => new RuntimeException("boom"))
s <- ZIO.fromFuture { implicit ec => bar(i)}
} yield s
在这种情况下,有几个运算符可以帮助您解决问题,基本上我建议结合使用 some
和 [,而不是使用 fromOption
显式解包 Option
=14=]
val t: Task[Option[String]] = (for {
// This moves the `None` into the error channel
i: Int <- ZIO.fromFuture(implicit ec => foo("test")).some
// This wraps the error in a Some() so that the signature matches
s: String <- ZIO.fromFuture(implicit ec => bar(i)).asSomeError
} yield s).optional // Unwraps the None back into the value channel
我刚刚开始评估 ZIO 以改进我的异步 Scala 代码的编程模型和性能。在我的代码库中,我经常处理 Future[Option[T]]
,到目前为止,我已经使用 Scalaz 的 OptionT
monad 转换器来处理它。现在我想用 ZIO 试试这个。
考虑两个函数:
def foo: String => Future[Option[T]]
和
def bar: T => Future[U]
我试过这样的事情:
val t = for {
o: Option[Int] <- ZIO.fromFuture { implicit ec =>
foo("test")
}
i: Int <- ZIO.fromOption(o)
s: String <- ZIO.fromFuture { implicit ec =>
bar(i)
}
} yield s
根据我的 IDE,t
在这种情况下属于 ZIO[Any, Any, String]
类型。我不知道该怎么办。
我想考虑三种可能:
- "success" 的情况
foo
产生一个Some
可以与值 上的其他函数组合
foo
产生None
的情况
- 任一函数产生错误的情况
我不确定如何使用 ZIO 解析这种情况下的这些可能性。感谢任何帮助。
ZIO.fromOption(o)
is IO[Unit, A]
which is ZIO[Any, Unit, A]
, whilst the type of ZIO.fromFuture
is Task[A]
which is ZIO[Any, Throwable, A]
, as documented by Type Aliases 的类型。因此类型不对齐
ZIO[Any, Unit, A]
ZIO[Any, Throwable, A]
尝试 mapError
将错误类型与 Throwable
对齐,就像这样
for {
o <- ZIO.fromFuture { implicit ec => foo("test") }
i <- ZIO.fromOption(o).mapError(_ => new RuntimeException("boom"))
s <- ZIO.fromFuture { implicit ec => bar(i)}
} yield s
在这种情况下,有几个运算符可以帮助您解决问题,基本上我建议结合使用 some
和 [,而不是使用 fromOption
显式解包 Option
=14=]
val t: Task[Option[String]] = (for {
// This moves the `None` into the error channel
i: Int <- ZIO.fromFuture(implicit ec => foo("test")).some
// This wraps the error in a Some() so that the signature matches
s: String <- ZIO.fromFuture(implicit ec => bar(i)).asSomeError
} yield s).optional // Unwraps the None back into the value channel