I'm trying to write a tail recursive function in the below way, but the compiler is throwing an error:
Too many arguments for method apply: (v1: Int)Int in trait Function1 else factorial(x-1, x*acc)
I had tried replacing Function1 with Function2 and gave Function2[Int, Int, Int] = new Function2[Int, Int, Int]
But it still threw me the same error. Can someone point out where i'm going wrong?
import scala.annotation.tailrec
var factorial: Function1[Int, Int] = new Function1[Int, Int] {
@tailrec override def apply (x:Int, acc:Int=1): Int = {
if (x<=1) acc
else factorial(x-1, x*acc)
}
}
factorial(5)
We can use factorial using recursion, but the function is not tail recursive. The value of fact(n-1) is used inside the fact(n).
The factorial function can be written as a recursive function call. Recall that factorial(n) = n × (n – 1) × (n – 2) × … × 2 × 1. The factorial function can be rewritten recursively as factorial(n) = n × factorial(n – 1).
Recursion is a method which breaks the problem into smaller subproblems and calls itself for each of the problems. That is, it simply means function calling itself. The tail recursive functions better than non tail recursive functions because tail-recursion can be optimized by compiler.
A recursive function is said to be tail-recursive if the recursive call is the last operation performed by the function. There is no need to keep a record of the previous state. In Scala, you can use @tailrec to check if the recursion is tail-recursive or not. The annotation is available in the scala. annotation.
You apply
inside Function1
must take only one param, when you are passing two.
You can rewrite it as follows:
var factorial: Function1[Int, Int] = new Function1[Int, Int] {
def apply (x:Int): Int = {
@tailrec def loop(x: Int, acc: Int = 1): Int = {
if (x<=1) acc
else loop(x-1, x*acc)
}
loop(x)
}
}
Function1
represents a function with a single parameter (the second one is for the output)
So you need to define your apply method with a single parameter, and then, inside it, do the recursion using a nested function:
import scala.annotation.tailrec
var factorial: Function1[Int, Int] = new Function1[Int, Int] {
override def apply(x: Int): Int = {
@tailrec
def go (x: Int, acc: Int = 1) : Int = {
if (x<=1) acc
else go(x-1, x*acc)
}
go(x)
}
}
factorial(5)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With