Reputation: 2982
I am curious if can implement a Scala function similar to this Javascript function. Obviously, I can do it easily with an inner function.
Knowing that Scala has to declare the parameter type and arity upfront, I just wonder if there is anything I could use to implement this JS function. Thanks.
function factorial(x) {
if (x < 0) throw Error("Cannot calculate factorial of a negative number");
return (function(f) {
return f(f, x, 1);
})(function(f, i, fact) {
return i === 0 ? fact : f(f, i-1, i*fact);
});
}
Upvotes: 1
Views: 345
Reputation: 1015
If I have understood your question correctly, indeed you can do this and the best known approach is to use what's called a Y-combinator. In short a Y-combinator takes a function as a parameter and keeps applying it. The Y-combinator has no knowledge of the parameter types involved
Copying the example Y-combinator right from rosetta code:
def Y[A,B](f: (A=>B)=>(A=>B)) = {
case class W(wf: W=>A=>B) {
def apply(w: W) = wf(w)
}
val g: W=>A=>B = w => f(w(w))(_)
g(W(g))
}
defines your combinator. You can then pass it your recursive function
val fac = Y[Int, Int](f => i => if (i <= 0) 1 else f(i - 1) * i)
fac: Int => Int = <function1>
And then give that something to evaluate
scala> fac(6)
res0: Int = 720
Upvotes: 6