Seq [Option [T]]到Option [Seq [T]]的“自然”功能是否有名称?

时间:2016-02-27 10:18:29

标签: scala functional-programming monads

这个函数(或者它的一些monadic泛化)是否具有已建立的名称?

def foo[T](in: Seq[Option[T]]): Option[Seq[T]] = {
    val res = in.flatten.seq
    if (res.length == in.length) Some(res) else None
}

是否有更优雅的实施?

1 个答案:

答案 0 :(得分:3)

正如评论中已经建议的那样,Seq[M[A]]M[Seq[A]](其中M是monad)的函数通常被称为sequence

Haskell对它的定义是:

  

从左到右评估序列中的每个动作,并收集结果。

scala标准库中没有通用的实现,但您可以在此处看到Future类型的示例:https://github.com/scala/scala/blob/v2.10.3/src/library/scala/concurrent/Future.scala#L487-L491

您可以在catsscalaz等库中找到sequence的通用实现。

需要注意的一点是,sequence是更通用操作的特定情况,通常称为traverse

Haskell将traverse定义为

  

将结构的每个元素映射到一个动作,从左到右评估这些动作,并忽略结果。

现在,根据定义,sequence可以用traverse实现,只需使用身份函数(x => x)作为traverse的映射操作即可。

如果你看看上面提到的实现,你会发现他们都利用了这种概括,他们都使用traverse来实现sequence