从 Seq[Option[T]] 到 Option[Seq[T]] 的 "natural" 函数有名字吗?
Does the "natural" function from Seq[Option[T]] to Option[Seq[T]] have a name?
这个函数(或者可能是它的一些单子泛化)有一个既定的名称吗?
def foo[T](in: Seq[Option[T]]): Option[Seq[T]] = {
val res = in.flatten.seq
if (res.length == in.length) Some(res) else None
}
有没有更优雅的实现方式?
正如评论中已经建议的那样,从 Seq[M[A]]
到 M[Seq[A]]
的函数(其中 M
是一个 monad)通常被称为 sequence
。
它的Haskell定义是:
Evaluate each action in the sequence from left to right, and collect the results.
scala 标准库中没有它的通用实现,但您可以在此处查看 Future
类型的示例:https://github.com/scala/scala/blob/v2.10.3/src/library/scala/concurrent/Future.scala#L487-L491
等库中找到 sequence
的通用实现
需要注意的一件事是,sequence
是更通用操作的特例,通常称为 traverse
。
Haskell 将 traverse
定义为
Map each element of a structure to an action, evaluate these actions from left to right, and ignore the results.
现在,根据定义,sequence
可以根据traverse
实现,只需使用身份函数(x => x
)作为[=19=的映射操作].
如果你看一下上面提到的实现,你会发现它们都利用了这个泛化,它们都使用 traverse
来实现 sequence
。
这个函数(或者可能是它的一些单子泛化)有一个既定的名称吗?
def foo[T](in: Seq[Option[T]]): Option[Seq[T]] = {
val res = in.flatten.seq
if (res.length == in.length) Some(res) else None
}
有没有更优雅的实现方式?
正如评论中已经建议的那样,从 Seq[M[A]]
到 M[Seq[A]]
的函数(其中 M
是一个 monad)通常被称为 sequence
。
它的Haskell定义是:
Evaluate each action in the sequence from left to right, and collect the results.
scala 标准库中没有它的通用实现,但您可以在此处查看 Future
类型的示例:https://github.com/scala/scala/blob/v2.10.3/src/library/scala/concurrent/Future.scala#L487-L491
sequence
的通用实现
需要注意的一件事是,sequence
是更通用操作的特例,通常称为 traverse
。
Haskell 将 traverse
定义为
Map each element of a structure to an action, evaluate these actions from left to right, and ignore the results.
现在,根据定义,sequence
可以根据traverse
实现,只需使用身份函数(x => x
)作为[=19=的映射操作].
如果你看一下上面提到的实现,你会发现它们都利用了这个泛化,它们都使用 traverse
来实现 sequence
。