Scala 中用于理解的多个生成器的通用函数
Generic function for multiple generators in for comprehensions in Scala
假设我想创建字母 "a" 和 "b" 的所有可能组合。对于使用 for-comprehensions 的长度 2 的组合,它将是:
for {
x <- Seq("a", "b")
y <- Seq("a", "b")
} yield x + y
对于长度为 3 的组合,它将是:
for {
x <- Seq("a", "b")
y <- Seq("a", "b")
z <- Seq("a", "b")
} yield x + y + z
非常相似。是否可以抽象这种模式并编写通用函数?
我能想到这样的签名:
def genericCombine[A,B](length: Int, elements: Seq[A])(reducer: Seq[A] => B): Seq[B]
如何参数化用于理解的生成器数量?
这更像是带替换的排列而不是组合,递归实现相当简单:
def select(n: Int)(input: List[String]): List[String] =
if (n == 1) input else for {
c <- input
s <- select(n - 1)(input)
} yield c + s
按预期工作:
scala> select(2)(List("a", "b"))
res0: List[String] = List(aa, ab, ba, bb)
scala> select(3)(List("a", "b"))
res1: List[String] = List(aaa, aab, aba, abb, baa, bab, bba, bbb)
(您当然应该在实际应用程序中检查无效输入。)
假设我想创建字母 "a" 和 "b" 的所有可能组合。对于使用 for-comprehensions 的长度 2 的组合,它将是:
for {
x <- Seq("a", "b")
y <- Seq("a", "b")
} yield x + y
对于长度为 3 的组合,它将是:
for {
x <- Seq("a", "b")
y <- Seq("a", "b")
z <- Seq("a", "b")
} yield x + y + z
非常相似。是否可以抽象这种模式并编写通用函数? 我能想到这样的签名:
def genericCombine[A,B](length: Int, elements: Seq[A])(reducer: Seq[A] => B): Seq[B]
如何参数化用于理解的生成器数量?
这更像是带替换的排列而不是组合,递归实现相当简单:
def select(n: Int)(input: List[String]): List[String] =
if (n == 1) input else for {
c <- input
s <- select(n - 1)(input)
} yield c + s
按预期工作:
scala> select(2)(List("a", "b"))
res0: List[String] = List(aa, ab, ba, bb)
scala> select(3)(List("a", "b"))
res1: List[String] = List(aaa, aab, aba, abb, baa, bab, bba, bbb)
(您当然应该在实际应用程序中检查无效输入。)