2013-04-25 76 views
3

什麼是Haskell的sequence功能的斯卡拉模擬的模擬? http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:sequence斯卡拉 - Haskell的序列

sequence是在Haskell定義如下:

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

參見[這個問題](HTTP實現它:/ /stackoverflow.com/q/12268351/334519)和[我的答案](http://stackoverflow.com/a/12269252/334519)。 – 2013-04-25 01:35:20

+0

還要注意,你只需要一個'sequence'的應用函子,所以Scalaz的版本比Haskell更普遍。 – 2013-04-25 01:37:41

+2

@TravisBrown:你的版本並不比Haskell的版本更通用。恰恰相反。查看'Data.Traversable'中的'sequenceA'。 – ertes 2013-04-25 02:08:49

回答

3

如果你不想使用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)