函數工廠Curry的威力

概述

「徹底」函數式編程 一文中,咱們初步感覺了函數式編程的力量:以很是簡潔的代碼,經過組合任何短小的簡單函數,實現更加複雜功能的複合函數。html

有小夥伴可能會問: 既然函數是這麼重要的原材料,那麼從哪裏能夠獲取這麼多原材料呢 ?總不成,一個個去定義吧。別急,Curry 提供了批量生產函數的能力,—— 若是星雲是恆星的工廠,那麼,Curry 就是函數的工廠。編程

本文將以 Groovy 爲示例,講解 Curry 的特性及能力。

框架

基礎知識

小夥伴都學過多元函數,好比 f(x,y) = x^2 + y ,當 y = 0 時,就變成 f(x) = x^2 平方函數; 當 x = 1 時,就變成 f(y) = 1+y 線性函數。 Curry ,通俗地說,就是將多變量的函數,經過逐個因變量賦值,從而批量生成函數的能力。函數式編程

以下代碼所示: def closure = { x,y -> x^2 +y } 定義了一個二元函數 f(x,y) , rcurry(0) 便是將 y 賦值爲 0 (右邊的參數),這樣就獲得了一元函數 square(x) = x^2 ; curry(1) 便是將 x 賦值爲 1 (默認是左邊的參數),就獲得了 linear(y) = 1+y 。 嗯,就是這麼簡單。函數

class Basics {

    static void main(args) {
        def closure = { x,y -> x * x +y }
        def square = closure.rcurry(0)

        println((1..5).collect { square(it) })

        def linear = closure.curry(1)
        println((1..5).collect { linear(it) })

    }
}

輸出結果:this

[1, 4, 9, 16, 25]
[2, 3, 4, 5, 6]


實際應用

那麼 Curry 有什麼實際應用呢 ? 總不能只停留在數學的領域裏。 實際上 Curry 的能力很是強大。咱們來實現一個通用調用器。在實際工程中,經常須要調用具備相同參數的函數,或者對不一樣的對象進行相同的處理。code

假設有兩個訂單處理函數: cancel, complete ,有一個列表排序函數 sort:htm

def static sort(list) {
        list.sort()
        return list
    }

    def static cancel(order) {
        println ("cancel: " + order.orderNo)
    }

    def static complete(order) {
        println ("complete: " + order.orderNo)
    }

class OrderParam {
    def orderNo
    def shopId
}

能夠定義一個二元函數 generalCaller ,能夠對指定的參數對象 param 使用指定的 handler 進行處理。對象

def generalCaller = { param, handler -> handler(param) }

如今,來看怎麼使用:blog

第一種方式:指定參數對象。 能夠構造一個訂單對象,使用 Curry ,就獲得了能夠處理這個訂單的函數處理器 orderProcessor, 而後就能夠傳入不一樣的訂單處理器進行處理。this.&method 是 Groovy 對函數的引用。

def orderProcessor = generalCaller.curry(new OrderParam(orderNo: 'E0001', shopId: 55))
orderProcessor(this.&cancel)
orderProcessor(this.&complete)

第二種方式,指定處理器。 就獲得了一個對參數進行排序的函數 sort(param) , 而後傳入不一樣的可排序對象進行處理:

def sorter = generalCaller.rcurry(this.&sort)
println sorter([4,7,2,6,1,3])
println sorter(["i", "have", "a", "dream"])

是否是很是靈活 ? 在 「函數柯里化(Currying)示例」 一文中,使用 Curry 實現了一個簡易的文件處理框架。

小結

Curry 能夠將高維函數逐步降維,批量生成大量的低維函數。 若是有一個 N 維函數,思考下,經過 Curry ,能夠生成多少個低維函數 ?Curry 結合函數式編程,蘊藏着驚人的潛力。

相關文章
相關標籤/搜索