Scala - 类似于Haskell中sequence的函数

5
Scala中与Haskell的`sequence`函数类似的是什么? http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:sequence 在Haskell中,`sequence`的定义如下:
sequence :: Monad m => [m a] -> m [a]
sequence ms = foldr k (return []) ms
            where
              k m m' = do { x <- m; xs <- m'; return (x:xs) }

以下是一些用途:

ghci> sequence [Just 1, Just 2, Nothing, Just 3]
Nothing
ghci> sequence [[1,2],[3,4],[5,6]]
[[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]

提前致谢!


1
请参考此问题和我的答案。链接如下:此问题我的答案 - Travis Brown
请注意,对于“sequence”函数,您只需要一个适用函子,因此Scalaz版本比Haskell的更通用。 - Travis Brown
2
@TravisBrown:你的版本并不比Haskell的版本更通用。相反,可以看看Data.Traversable中的sequenceA函数。 - ertes
@ertes:更一般地说,Scalaz 的适用函子不一定是单子(例如 Validation),而 Prelude 的则不行。是的,有 sequenceA,但问题提到的是 sequence - Travis Brown
@TravisBrown:我只是给出了Prelude序列作为参考点 - 我对Scala还很陌生,Scalaz的sequence是否可以在可遍历和可折叠的函数子类上工作,就像Haskell中的sequenceA实现一样? - Matt W-D
1个回答

4

如果您不想使用scalaz,那么您可以自己实现它

def map2[A,B,C](a: Option[A], b: Option[B])(f: (A,B) => C): Option[C] =
  a.flatMap { x => b.map { y => f(x, y) } }

def sequence[A](a: List[Option[A]]): Option[List[A]] =
  a.foldRight[Option[List[A]]](Some(Nil))((x,y) => map2(x,y)(_ :: _))

或者使用遍历的替代实现

def traverse[A, B](a: List[A])(f: A => Option[B]): Option[List[B]] =
  a.foldRight[Option[List[B]]](Some(Nil))((h,t) => map2(f(h),t)(_ :: _))

def sequence[A](seq: List[Option[A]]): Option[List[A]] = traverse(seq)(identity)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接