これは本当に良い質問です!
flatMap
を任意のサイズの要素のリストの上に順番に実行します。あなたのリストがどれくらいの長さであるか分からないときは、再帰で処理することも、等価的に折り畳みで処理することもできます。
scala> def sequence[A](lss: List[List[A]]) = lss.foldRight(List(List[A]())) {
| (m, n) => for (x <- m; xs <- n) yield x :: xs
| }
scala> sequence(List(List(1, 2), List(4, 5), List(7)))
res2: List[List[Int]] = List(List(1, 4, 7), List(1, 5, 7), List(2, 4, 7), List(2
, 5, 7))
(あなたは、コードを理解することはできません場合は、Hoogleとsteal it from Haskellを使用する方法を学び、心配しないでください)
あなたはScalazでこれを行うことができます(一般的には、それはF[G[X]]
で始まり、型コンストラクタG
とF
それぞれTraverse
とApplicative
能力を有することを考えると、G[F[X]]
を返す。
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> List(List(1, 2), List(4, 5), List(7)).sequence
res3: List[List[Int]] = List(List(1, 4, 7), List(1, 5, 7), List(2, 4, 7), List(2
, 5, 7))
scala> Seq(some(1), some(2)).sequence
res4: Option[Seq[Int]] = Some(List(1, 2))
scala> Seq(some(1), none[Int]).sequence
res5: Option[Seq[Int]] = None
再帰によっても可能ですが、 'f'が値のリストを受け入れる場合のみです。 –
私はこの制限なしで(fは標準のパラメータリストを取るか、またはカレー化しています)、この問題を解決することを望んでいました。 – schmmd