Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a factorial tail recursive function in Scala

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)
like image 638
Vasu Avatar asked Dec 27 '17 13:12

Vasu


People also ask

Is factorial tail recursive?

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).

How do you write a recursive factorial?

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).

Does Scala support tail recursion?

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.

What is recursion and tail recursion in Scala?

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.


2 Answers

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)
  }
}
like image 59
Yevhenii Popadiuk Avatar answered Oct 19 '22 08:10

Yevhenii Popadiuk


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)
like image 26
SCouto Avatar answered Oct 19 '22 07:10

SCouto