Konwertuj zwykłą rekursję na rekursję ogona

Zastanawiałem się, czy istnieje jakaś ogólna metoda konwersji „normalnej” rekursji za pomocąfoo(...) + foo(...) jako ostatnie wezwanie do rekursji ogonowej.

Na przykład (scala):

def pascal(c: Int, r: Int): Int = {
 if (c == 0 || c == r) 1
 else pascal(c - 1, r - 1) + pascal(c, r - 1)
}

Ogólne rozwiązanie dla języków funkcjonalnych do konwersji funkcji rekurencyjnej na ekwiwalent połączenia ogonowego:

Prostym sposobem jest zawinięcie funkcji rekursywnej bez ogona wTrampoline monad.

def pascalM(c: Int, r: Int): Trampoline[Int] = {
 if (c == 0 || c == r) Trampoline.done(1)
 else for {
     a <- Trampoline.suspend(pascal(c - 1, r - 1))
     b <- Trampoline.suspend(pascal(c, r - 1))
   } yield a + b
}

val pascal = pascalM(10, 5).run

Tak więc funkcja pascal nie jest już funkcją rekurencyjną. Jednakże monada trampoliny jest zagnieżdżoną strukturą obliczeń, którą należy wykonać. Wreszcie,run jest funkcją rekurencji ogonowej, która przechodzi przez strukturę podobną do drzewa, interpretując ją, aw końcu w przypadku bazowym zwraca wartość.

Artykuł Rúnara Bjanarsona na temat trampolin:Bezskala Scala z wolnymi monadami

questionAnswers(6)

yourAnswerToTheQuestion