2014-09-20 43 views
0

我認爲這可能是非常基本的問題。 我們在函數式編程中使用了哪些不同類型的遞歸。 以及我們使用Erlang編程語言的什麼樣的遞歸。erlang中的不同種類的轉換

+0

我不完全明白這個問題。遞歸與其他語言相同。一個「特殊」的事情是優化「尾遞歸」函數。你想知道更多關於這個話題還是關於一般遞歸http://en.wikipedia.org/wiki/Recursion_(computer_science)#Types_of_recursion – tkowal 2014-09-20 10:58:56

回答

1

我會建議尋找到Learn You Some Erlang,因爲它是這個主題的漂亮和全面的描述。

總之,有兩種類型,由語義而非語法區分。

有基本徵用可以看到在幾乎任何其他語言

fibonacci (0) -> 
    0; 
fibonacci (1) -> 
    1; 
fibonacci(X) when X > 1 -> 
    fibonacci(X-1) + fiboancci(X-2). 

而這正與預期堆棧內存的使用情況(新的堆棧,幾乎每個函數調用。

而且還有一種叫尾遞歸。當遞歸函數最後被調用時,編譯器可以跳過每個調用創建新的堆棧,因爲會有沒有必要杉平倉,返回返回上級任何其他邏輯。所有這一切都需要做的是返回一個最終值,理解它是讓我們更深入地看看我們的例子。

在上面的fibonacci中,被調用的最後一個函數是兩個數字的相加。我們可以把這個功能使用某種計數器類似於其他語言環路,蓄能器,這將在年底(B)返回

fibonacci(X) -> 
    fibonacci(X, 0, 1). 

fibonacci(1, _A, B) -> 
    B; 
fibonacci(Counter, A, B) -> 
    fibonacci(Counter-1, B, A+B). 

這一次函數fibonacci/3可以不stack unwinding執行。它仍然是遞歸,具有所有相同的規則和邏輯,但它能夠更快地運行(並且沒有太多的內存消耗)。

在Erlang中尾遞歸的這種可能性,有一個重要的consequance。它允許長時間(永久)運行的進程。如果你看幾乎所有的演員與receive條款它法洛斯類似的模式

loop(SomeState) -> 
    receive 
     PatterMatch -> 
      [ .. Do some stuff .. ] 
      loop(UpdatedState); 

     AnotherPatternMatch -> 
      [.. different actions ..] 
      loop(UpdatedStte); 

     stop -> 
      ok 
    end. 

你可以很容易地發現,loop/1功能是遞歸的。事實上,它是tali遞歸允許它被多次調用,而不會增加此進程的內存使用量。

StackEdit書面。