recursive or iterative

假設(shè)我們需要一個string * list * list 類型的值需要處理,并返回一個去掉制定字符串的string list 類型的程序。我們怎么處理?

這是一個非常簡單的程序,我像用這個非常簡單的問題介紹recursive 和 iterative 兩種方法。

首先定義比較字符串的函數(shù),然后定義option的類型,為recursive和iterative

fun same_string(s1 : string, s2 : string) =
  s1 = s2

fun all_except_option(lst, str) =
  case lst of
      [] => NONE
    | ls::ls' => if same_string(ls,str)
                 then SOME ls'
                 else case all_except_option(ls', str) of
                          NONE => NONE
                        | SOME xs => SOME(ls::xs) 

首先我們實現(xiàn)recursive 的函數(shù)

fun get_substitutions1(str_lst_lst, str) =
  case str_lst_lst of
      [] => []
    | ls::lst => case all_except_option(ls, str) of
                     NONE => get_substitutions1(lst, str)
                   | SOME xs => xs @ get_substitutions1(lst,str)

再看看 iterative

fun get_substitutions2(str_lst_lst, str) =
  let fun aux(lst, acc) =
        case lst of
            [] => acc
          | ls::ls' => case all_except_option(ls, str) of
                           NONE => aux(ls', acc)
                         | SOME xs => aux(ls', acc @ xs)
  in
      aux(str_lst_lst, [])
  end

可以看到,我們最上面的遞歸形式被我在夏目按改成了尾遞歸形式,尾遞歸形式的開銷更小。

他們在repl中自動推導(dǎo)的類型是這樣的


可以看到他們是一模一樣的,只是后面一種不會棧溢出,開銷更小。


我為什么想寫這個內(nèi)容呢,我想說的是 一個語言根本不需要while這種循環(huán)類的關(guān)鍵字,遞歸更加的powerful。

那么問題來了,我的itreative是在編譯器尾遞歸優(yōu)化的情況下才做到不會導(dǎo)致棧溢出,如果編譯器十分的古老,沒有尾遞歸,這個時候你不需要循環(huán)么?

答案仍然是不需要,這是一個非常有趣的問題,我們可以通過continuation-passing style (CPS)來解決這件事,過一段時間,我會來填這個cps的坑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容