Reputation: 1988
If the last statement in a function is func(x,tailList):
def func(x:Int):List[Int]...
case head :: tailList => head :: func(x,tailList)
converting this function to tail recursion requires accumulator to be added as a third parameter (and to keep it clean adding a local function inside func() ).
insertTail(x,tailList,head::acc)
doesn't seem to work correctly. shouldn't "acc" hold the computation in progress?
Am I missing something here to make it tail recursive work with accumulator?
Adding a more complete example
def funcTailTest(x:Int,xs:List[Int]):List[Int] = {
@tailrec
def inner(x:Int,xs:List[Int],acc:List[Int]) : List[Int] = xs match {
case head::tailList => {
inner(x,tailList,head::acc)
}
}
inner(x,xs,Nil)
}
basically head should be added to the output of inner() function so w/o an attempt to make it tail recursive last statement in a case will look
head::inner(x,tailList)
Upvotes: 0
Views: 1847
Reputation: 748
Following is a scala function to implement Tail recursion using cons operator
def reverseUtility(ele: List[Int], res: List[Int]):List[Int] ={
ele match {
case Nil => Nil
case x :: Nil => x :: res
case x :: y => reverseUtility(y, (x::res))
}}
Pass a list of Int
and an empty list called res(result)
as parameters for the function. Time complexity for the function is O(N)
Upvotes: 1
Reputation: 12852
Assuming that reverse is also tail recursively implemented (which it definitely can be), the following is a tail recursive append:
def append[T](y: T, xs: List[T]): List[T] = {
@tailrec
def appendAcc[T](y: T, xs: List[T], acc: List[T]): List[T] = xs match {
case Nil => y :: acc
case x :: xs => appendAcc(y, xs, x :: acc)
}
appendAcc(y, xs, Nil).reverse
}
Upvotes: 1