天天看點

haskell中的函數柯裡化和高階函數

函數柯裡化指的是“一個接收多個參數的函數實際上每次隻接收一個參數,然後傳回一個接收下一個參數的另外一個函數,此過程重複下去,直到所有參數接收完畢,并在最後傳回結果”。這也是haskell中函數的性質--所有的函數實際上隻也隻能接收一個參數,但是有些函數接收了多個參數是因為它們傳回了另外一個接收一個參數的函數。
    高階函數指的是:函數可以被當做參數傳給另外的函數,也可以被當做傳回值從某個函數傳回。總之,haskell中函數是一等公民。
    高階函數的好處在于,它往往能帶來更好的可讀性,更強的靈活性,以及更少的代碼量。
    以java為例,假設你手頭有兩個數組,有一天來了一個任務,你需要把他們的每一項依次相加然後填充到另外一個數組裡,即你需要從數組a[1,2,3]和數組b[4,5,6]得到數組c[5,7,9]。然後你寫了一個小函數搞定了這件事。然後有過了幾天你有了新的任務,你要把他們的每一項依次相乘然後填充到另外一個數組裡..這樣的相似的任務每天都來,相減..平方相加..立方相加..每次來了新任務都要寫這麼一堆的代碼,代碼量成倍增長,最後那些函數看起來一坨一坨的臃腫又難看。
    這時候高階函數就派上用場了。在haskell中,完成這些任務簡直不能再簡單。假設能夠完成這些任務的函數名字叫perfect
    ```
    perfect :: (a->b->c)->[a]->[b]->[c]
    perfect _ _ []=[]
    perfect _ [] _=[]
    perfect f (x:xs) (y:ys)=f x y:perfect f xs ys
    ```
    **是的,這就結束了。**那麼它是怎麼工作的呢?
    假設a=[1,2,3] b=[4,5,6]
    當我們需要清單相加的時候,perfect (+) a b
    當我們需要清單相乘的時候,perfect (*) a b
    當我們需要清單相除的時候,perfect (/) a b
    而當我們需要清單平方之後再相加的時候,我們就可以自己寫一個f函數傳進去:
    ```
    shit :: (Num a)=>a->a->a
    shit a b=a^2+b^2
    ```
    perfect shit a b
    這樣就解決了平方相加的問題了。
    如你所見,函數式程式設計能提供的抽象服務還遠不止于此,高階函數隻不過是個開始。不過講真,純函數其實并不是一個很好的選擇,我覺得現代語言的發展趨勢應該是在傳統的指令式程式設計中加上一些函數式程式設計的特性,這樣寫起來既不燒腦又能很優雅。