用于理解Scala中的动态深度

用于理解Scala中的动态深度,scala,functional-programming,Scala,Functional Programming,我正在编写一个代码,需要生成所有整数序列的组合,这些组合(元素)在其他两个整数序列的范围内。代码的可读性可能比上述解释更高: def combinations(startingCounts: List[Int], endingCounts: List[Int] ) = for( a <- startingCounts(0) to endingCounts(0); b <- startingCounts(1) to endingCounts(1); c <- star

我正在编写一个代码,需要生成所有整数序列的组合,这些组合(元素)在其他两个整数序列的范围内。代码的可读性可能比上述解释更高:

def combinations(startingCounts: List[Int], endingCounts: List[Int] ) = for(
  a <- startingCounts(0) to endingCounts(0);
  b <- startingCounts(1) to endingCounts(1);
  c <- startingCounts(2) to endingCounts(2)
) yield List(a, b, c)

combinations(List(0,7,3), List(1,7,5)) 
//^returns Vector(List(0, 7, 3), List(0, 7, 4), List(0, 7, 5), List(1, 7, 3), List(1, 7, 4), List(1, 7, 5))
def组合(起始计数:列表[Int],结束计数:列表[Int])=for(

a这是我的初始解决方案。看起来还可以,但我想知道是否可以做得更好

import scala.annotation.tailrec

type SLInt = IndexedSeq[List[Int]]
def combinations2(startingCounts: List[Int], endingCounts: List[Int] ): SLInt = {
  @tailrec
  def inner(acc: SLInt, startingCounts: List[Int], endingCounts: List[Int]): SLInt = {
    (startingCounts, endingCounts) match {
      case (sh :: st, eh :: et) if (sh <= eh) => {
        val newAcc = for(
          ls <- acc;
          last <- (sh to eh)
        ) yield (last :: ls)
        inner(newAcc, st, et)
      }
      case (Nil, Nil) => acc
      case _ => throw new IllegalArgumentException()
    }
  }
  inner(IndexedSeq(List()), startingCounts.reverse, endingCounts.reverse)
}

combinations2(List(0,7,3), List(1,7,5))
//res3: SLInt = Vector(List(0, 7, 3), List(1, 7, 3), List(0, 7, 4), List(1, 7, 4), List(0, 7, 5), List(1, 7, 5))
import scala.annotation.tailrec
类型SLInt=IndexedSeq[List[Int]]
def组合2(开始计数:列表[Int],结束计数:列表[Int]):SLInt={
@泰勒克
def内部(acc:SLInt,起始计数:列表[Int],结束计数:列表[Int]):SLInt={
(开始计数,结束计数)匹配{
案例(sh::st,eh::et)如果(sh){
val newAcc=用于(
ls抛出新的IllegalArgumentException()
}
}
内部(IndexedSeq(List()),开始计数.reverse,结束计数.reverse)
}
组合2(列表(0,7,3),列表(1,7,5))
//res3:SLInt=Vector(列表(0,7,3)、列表(1,7,3)、列表(0,7,4)、列表(1,7,4)、列表(0,7,5)、列表(1,7,5))
结果的顺序不同,但这没有什么区别。我正在执行
列表。反转
以避免使用
列表
追加操作,而是使用prepend,这应该是常数时间。

这怎么样

def combinations(startingCounts: List[Int], endingCounts: List[Int] ) : IndexedSeq[List[Int]] = {
  if(startingCounts.isEmpty)
    IndexedSeq(Nil)
  else 
    for{
      ns <- combinations(startingCounts.tail, endingCounts.tail)
      n <- startingCounts.head to endingCounts.head
    } yield 
      n :: ns
}
def组合(开始计数:List[Int],结束计数:List[Int]):IndexedSeq[List[Int]={
如果(开始计数。isEmpty)
IndexedSeq(无)
其他的
为了{
ns