Scala - 匿名函数的递归

loc*_*zak 6 recursion scala anonymous-function

我正在研究scala labs的东西,我正在构建一个函数,最终会返回这样的东西: tails(List(1,2,3,4)) = List(List(1,2,3,4), List(2,3,4), List(3,4), List(4), List())

我通过使用两个函数并在第二个函数上使用一些递归来实现此功能.

def tails[T](l: List[T]): List[List[T]] = {
    if ( l.length > 1 )trailUtil(List() ::: List(l))
    else List() ::: List(l);
}

def trailUtil[T](l:List[List[T]]) : List[List[T]] = {
    if ( l.last.length == 0)l
    else trailUtil(l :+ l.last.init);
}
Run Code Online (Sandbox Code Playgroud)

这一切都很好,但是我需要两个函数才能做到这一点.我尝试切换:trailUtil(List() ::: List(l))对于匿名函数,但我type mismatch; found :List[List[T]] required:Int从IDE 得到了这个错误.

val ret : List[List[T]] = (ll:List[List[T]]) => {
    if ( ll.last.length == 0) ll else ret(ll :+ ll.last.init)
}
ret(List() ::: List(1))
Run Code Online (Sandbox Code Playgroud)

有人可以指出我做错了什么,或者更好的做法,这将是伟大的.

(我确实看过这个 SO帖子但不同的类型对我不起作用):

Tom*_*icz 4

那这个呢:

def tails[T](l: List[T]): List[List[T]] = 
  l match {
    case h :: tail => l :: tails(tail)
    case Nil => List(Nil)
  }
Run Code Online (Sandbox Code Playgroud)

还有一个不太惯用的版本:

def tails[T](input: List[T]): List[List[T]] =
    if(input.isEmpty)
        List(List())
    else
        input :: tails(input.tail)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,尽量避免List.length,它在 O(n) 时间内运行。

更新:根据tenshi的建议,尾递归解决方案:

@tailrec def tails[T](l: List[T], init: List[List[T]] = Nil): List[List[T]] =
    l match {
        case h :: tail => tails(tail, l :: init)
        case Nil => init
    }
Run Code Online (Sandbox Code Playgroud)