Scala - EitherT 的展平序列
Scala - Flatten Sequence of EitherT
假设我有以下内容:
val ints: Seq[Int] = ???
def foo(i: Int): EitherT[Future, Error, Seq[String]] = ???
我想用 ints
调用 foo
并累积 Seq[String]
结果最终 return EitherT[Future, Error, Seq[String]]
.
ints.map(i => foo(i))
显然上面的 returns Seq[EitherT[Future, Error, Seq[String]]]
这不是我想要的。当foo
returnsError
第一次在map
时,我想停止遍历并且return报错。
实现我的目标的正确方法是什么?
ints.map(foo).reduce(for { a <- _ ; b <- _ } yield a ++ b)
这基本上可以满足您的要求,但我认为它不完全符合这句话的要求:
When the foo returns Error for the first time in the map, I want to
stop traversing and return the error.
问题是您需要在任何期货完成之前遍历 seq,因此您还不知道它们是否 return 错误。您可以 "block" 一个接一个地调用 foo
直到上一个调用完成,然后再调用 foo
,但这样您就无法获得任何并行性。理论上,可以启动所有这些期货,然后在一个 return 出现错误时取消仍然 运行 的期货,但不幸的是,取消期货并不是一件自然容易的事情。
假设我有以下内容:
val ints: Seq[Int] = ???
def foo(i: Int): EitherT[Future, Error, Seq[String]] = ???
我想用 ints
调用 foo
并累积 Seq[String]
结果最终 return EitherT[Future, Error, Seq[String]]
.
ints.map(i => foo(i))
显然上面的 returns Seq[EitherT[Future, Error, Seq[String]]]
这不是我想要的。当foo
returnsError
第一次在map
时,我想停止遍历并且return报错。
实现我的目标的正确方法是什么?
ints.map(foo).reduce(for { a <- _ ; b <- _ } yield a ++ b)
这基本上可以满足您的要求,但我认为它不完全符合这句话的要求:
When the foo returns Error for the first time in the map, I want to stop traversing and return the error.
问题是您需要在任何期货完成之前遍历 seq,因此您还不知道它们是否 return 错误。您可以 "block" 一个接一个地调用 foo
直到上一个调用完成,然后再调用 foo
,但这样您就无法获得任何并行性。理论上,可以启动所有这些期货,然后在一个 return 出现错误时取消仍然 运行 的期货,但不幸的是,取消期货并不是一件自然容易的事情。