<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理
        Lich Ray寫了個帖子《函數式編程語言曲高和寡?》,用快速排序的例子來說明函數式編程在表達思想方面比命令式語言更容易,其實這一點毋庸置疑,如果你正在讀或者讀過SICP的話。文中給了haskell、scheme和javascript的實現例子,我也湊趣寫了個Erlang版本,haskell我不了解就不說了,其他實現分別如下:
    scheme:
    (define (qsort ls)  
         (
    if (null? ls) '()  
             (let  
                 ((x (car ls))  
                 (xs (cdr ls)))  
                 (let   
                     ((lt (filter (lambda (y) (< y x)) xs))  
                     (st (filter (lambda (y) (>= y x)) xs)))  
                     (append (qsort lt) (list x) (qsort st))))))  

    javascript:
        // 把要用到的表達式抽象出來  
        Array
    .prototype.head = function () {  
            
    return this[0];  
        }  
          
        Array
    .prototype.tail = function () {  
            
    return this.slice(1);  
        }  
          
       Array
    .prototype.filter = function (proc) {  
           var tmpArr 
    = [];  
           
    for (var i = 0; i < this.length; i++)  
           
    if (proc(this[i]) == true)  
               tmpArr
    .push(this[i]);  
           
    return tmpArr;  
       }  
       Array
    .prototype.qsort = function () {  
           
    if (this == false) return []  
            var x
    , xs, lt, st  
           x 
    = this.head()  
            xs 
    = this.tail()  
            lt 
    = xs.filter(function (y) {return y < x})  
            st 
    = xs.filter(function (y) {return y >= x})  
            
    return lt.qsort().concat([x], st.qsort())  
        }  
    用Erlang的話,Erlang的list其實跟scheme的list是一樣的,甚至連定義的基本高階函數都一樣:map,filter,append等等,利用lists模塊提供的filter和append,我們可以寫出:
        qsort([])->[];  
        qsort([H
    |T])->  
            Lt
    =lists:filter(fun(E)->E<H end,T),  
            St
    =lists:filter(fun(E)->E>=H end,T),  
        lists
    :append(qsort(Lt),lists:append([H],qsort(St))).  
        我們來比較下scheme和Erlang版本,兩者最顯著的不同是,scheme使用了條件語句if,而Erlang卻是通過模式匹配來代替條件分支判斷。同樣,在list的分解上面,Erlang也是利用了規則匹配來代替car,cdr函數,從這里可以看出規則匹配在Erlang中的主要作用:分解復雜數據結構以便賦值和條件分支的分派。
        扯遠些可以談到模式匹配是以“like-a”來代替消息分派在傳統命令式語言中嚴格的“is-a”,這也跟現實世界的情況更為符合,現實世界中我們對事物的判斷都是模糊。而這一點,不正是“Duck-Typing”?傳統語言對于對象的類型(type)判斷來源于嚴格確定對象是什么類(class),不是這個類它就沒有相應的方法,而事實上類與類型這兩個概念并不是一致的,對象的類型更應該根據對象能夠做什么來決定。扯遠了,這只是我讀《失蹤的鏈環》得來的感受,如果對模式匹配還有懷疑的話,讓我們回到這個例子的Erlang版本,代碼中我們調用了兩次filter進行全表掃描,以便得到根據H切割的大小兩個部分,這在性能上有不小的影響,那么我們能不能只進行一次全表掃描呢,返回結果是“大小”兩個部分,看看Erlang應該怎么寫:
    sort([]) -> [];
    sort([Pivot|Rest]) ->
       {Smaller, Bigger} = split(Pivot, Rest),
       lists:append(sort(Smaller), [Pivot|sort(Bigger)]).
    split
    (Pivot, L) ->
    split(Pivot, L, [], []).
    split(Pivot, [], Smaller, Bigger) ->
    {Smaller
    ,Bigger};
    split(Pivot, [H|T], Smaller, Bigger) when H < Pivot ->
    split(Pivot, T, [H|Smaller], Bigger);
    split(Pivot, [H|T], Smaller, Bigger) when H >= Pivot ->
    split(Pivot, T, Smaller, [H|Bigger]).

        這幾行代碼充分展現了模式匹配的威力,不過Erlang其實有內置的方法partition用于切割list的,這里只是為了展現模式匹配,因此上面的代碼可以改為:
    sort([]) -> [];
    sort([Pivot|Rest]) ->
    {Smaller
    , Bigger} = lists:partition(fun(E)->E<Pivot end, Rest),
    lists
    :append(sort(Smaller), [Pivot|sort(Bigger)]).

    同樣的代碼改寫為ruby版本:
    def qsort(array)
      arr=array.dup
      
    if arr==[]
        []
      
    else
        x
    =arr.shift
        smaller
    ,bigger=arr.partition{|e| e<=x}
        qsort(smaller)
    +[x]+qsort(bigger)
      end
    end
        ruby與Erlang都有并行賦值,但是ruby不支持模式匹配。請注意ruby并沒有尾遞歸優化,因此上面的代碼在數組比較大的時候會導致棧溢出,想用ruby做函數式編程應該盡量多使用循環和map,filter,collect等輔助高階函數。
        另外一個Erlang與ruby、scheme比較重要的區別是Erlang的變量只能賦值一次(或者說綁定),也就是single assignment。這個特點與Erlang所要滿足的運行場景有緊密關系,當系統發生錯誤時,就可以從原來的值重新啟動任務,而不用擔心由于變量值的變化導致系統恢復困難。




    主站蜘蛛池模板: 爱情岛论坛免费视频| 免费A级毛片av无码| 黄色网址免费在线观看| 国产美女无遮挡免费网站| 精品亚洲视频在线观看 | 久久久久亚洲av无码专区喷水| 亚洲视屏在线观看| 免费91最新地址永久入口| 亚洲熟伦熟女新五十路熟妇 | 亚洲AV无码成H人在线观看| 亚洲乱码国产乱码精品精| 成人a毛片视频免费看| 在线永久看片免费的视频| 亚洲熟妇无码久久精品| 真人做人试看60分钟免费视频| 亚洲av无码片区一区二区三区| 一区二区免费电影| 国产亚洲精品拍拍拍拍拍 | 最近免费中文字幕高清大全| 四虎永久免费观看| 黄色一级视频免费观看| 国产日产亚洲系列最新| 免费无码H肉动漫在线观看麻豆| 免费鲁丝片一级在线观看| 亚洲精品~无码抽插| 小日子的在线观看免费| 亚洲国产日韩在线人成下载| 中文字幕乱码免费看电影| 免费中文字幕在线观看| 国产精品亚洲午夜一区二区三区| 无码少妇一区二区浪潮免费| 亚洲精品久久无码av片俺去也 | 久久免费国产精品一区二区| 亚洲人成网www| 成年女人免费视频播放体验区| 麻豆安全免费网址入口| 亚洲国产三级在线观看| 99热在线精品免费全部my| 国产亚洲美女精品久久| 亚洲AV无码专区亚洲AV伊甸园| 无码区日韩特区永久免费系列|