2016-01-27 2 views
1

Мне любопытно, может ли реализовать функцию Scala, подобную этой функции Javascript. Очевидно, что я могу сделать это легко с помощью внутренней функции.Функция Scala с параметром рекурсивной функции

Зная, что Scala должно объявлять тип параметра и arity upfront, мне просто интересно, есть ли что-нибудь, что я мог бы использовать для реализации этой функции JS. Благодарю.

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); 
    }); 
} 
+0

Я запутался, что ваш вопрос здесь - вы спрашиваете, если вы можете создать функцию, которая принимает рекурсивная функция как параметр? – Hamish

ответ

6

Если я правильно понял ваш вопрос, на самом деле вы можете сделать это и самый известный подход заключается в использовании, что называется Y-combinator. Короче говоря, Y-комбинатор выполняет функцию в качестве параметра и продолжает применять его. Y-комбинатор не имеет сведений о типах параметров, участвующих

Копирование примера Y-комбинатор прямо из 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)) 
} 

определяет ваш комбинатор. Затем вы можете передать его вашей рекурсивной функцию

val fac = Y[Int, Int](f => i => if (i <= 0) 1 else f(i - 1) * i) 
fac: Int => Int = <function1> 

А потом дать что-то, чтобы оценить

scala> fac(6) 
res0: Int = 720 
+0

Смутно красивый. – marios