Swift 函數(shù)式編程探索(3)—— Applicative 和 Curry

前兩篇說了 monad 和 functor 枢冤,這兩個算是比較經(jīng)常會實際使用的薯鼠。
這里說的兩個函數(shù)式編程 Feature ,相對就沒有那么廣泛的使用了昨凡。
Applicative 和 Curry 铐然,其中 applicative 并沒有在 swift 中原生集成(雖然實現(xiàn)起來也很容易)蔬崩, Curry 在 swift 3.0 中被移除了(雖然自己實現(xiàn)起來還是很容易)。
這里用到的代碼我都寫在了 playground 里搀暑,放到了 Github

這里簡單說一下吧沥阳。

1. Applicative

只要實現(xiàn)了 Apply 函數(shù)如何作用于自身,就是一個 Applivative自点。

Optional 的 Apply

我們可以這樣對 optional 和 SequenceType 擴充一個 apply 方法:

extension Optional {
    func apply<T>(f: (Wrapped -> T)?) -> T? {
        if let f = f {
            return self.map(f)
        }
        return nil
    }
}

這樣 Optional 就是一個 Applivative 了桐罕,我們可以這樣來使用:

let b = Optional.Some(1)
let a = Optional.Some({ $0 + 1 })
b.apply(a)  // 返回 Optional(2)
SequenceType 的 Apply

我們同樣可以對 SequenceType 擴充一個 apply 方法

extension SequenceType {
    func apply<T>(fs: [Generator.Element -> T]) -> [T] {
        var result = [T]()
        for f in fs {
            for element in self.map(f) {
                result.append(element)
            }
        }
        return result
    }
}

這樣一來 SequenceType 也是 Applicative 了。
我們可以怎么使用呢桂敛?

let plusTwoAndThree = [ { $0 * 2 }, { $0 * 3 } ]
let ints = [1, 2, 3]
ints.apply(plusTwoAndThree)  // 返回 [2, 4, 6, 3, 6, 9]
實踐

和 functor 和 monad 類似功炮,我們定義一個操作符 <*>

infix operator <*> { associativity left }

func <*><U, T>(f: (U -> T)?, a: U?) -> T? {
    return a.apply(f)
}

func <*><S: SequenceType, T>(f: [S.Generator.Element -> T], a: S) -> [T] {
    return a.apply(f)
}

然后我們就可以這樣:

a <*> b
plusTwoAndThree <*> ints

2. Curry

簡單地來說,Curry 就是一個生成方法的方法
比如說這里:

func operate(num: Int) -> (Int -> Int) -> Int {
    return {
        operate in operate(num)
    }
}

這是一個接收一個 Int 參數(shù)术唬,返回一個接受一個 Int -> Int 參數(shù)的方法薪伏,再返回 Int
這么說可能有點繞,比如我們使用這個方法:

let operateOne = operate(1)  // (Int -> Int) -> Int

這里的 operateOne 就是一個生成的方法粗仓,它接受一個 Int -> Int 方法嫁怀,然后返回 Int
我們可以拿這個 operateOne 這么使用:

let addOne: Int -> Int = { $0 + 1 }
let addTwo: Int -> Int = { $0 + 2 }

operateOne(addOne)  // 返回2
operateOne(addTwo)  // 返回3

使用 curry 能夠量產(chǎn)方法,可以避免寫一些重復(fù)的代碼借浊。

實踐

在 swift 3.0 中塘淑,已經(jīng)把 curry 函數(shù)移除了,詳情可以見這里:
remove-currying

  // Before:
  func curried(x: Int)(y: String) -> Float {
    return Float(x) + Float(y)!
  }

像這種已經(jīng)不能寫了蚂斤,但是可以用這種方法存捺,也能輕易實現(xiàn):

  // After:
  func curried(x: Int) -> (String) -> Float {
    return {(y: String) -> Float in
      return Float(x) + Float(y)!
    }
  }

但是我們不是都有機會去修改代碼的,比如說一些第三方庫什么的曙蒸,我們可以用這樣的泛型函數(shù)生成一個柯里函數(shù):

func curry<A,B,R>(fun: (A,B) -> R) -> A -> B -> R {
    return { a in { b in fun(a,b) } }
}

這么使用:

func operate(num: Int, f: Int -> Int) -> Int {
    return f(num)
}

let curryOperate = curry(operate)

curryOperate(1)(addOne)  // 返回 2

curry 和 applicative 也是函數(shù)式編程的重要部分捌治,但是相對于 map 和 flatMap ,并沒有在 swift 中那么多的使用纽窟,但是掌握了它們具滴,仍然能為我們帶來更好的開發(fā)思維,具體可以如何使用呢师倔?
可以看一看我的這一篇:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子趋艘,更是在濱河造成了極大的恐慌疲恢,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓷胧,死亡現(xiàn)場離奇詭異显拳,居然都是意外死亡,警方通過查閱死者的電腦和手機搓萧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門杂数,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瘸洛,你說我怎么就攤上這事揍移。” “怎么了反肋?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵那伐,是天一觀的道長。 經(jīng)常有香客問我石蔗,道長罕邀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任养距,我火速辦了婚禮诉探,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘棍厌。我一直安慰自己肾胯,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布定铜。 她就那樣靜靜地躺著阳液,像睡著了一般。 火紅的嫁衣襯著肌膚如雪揣炕。 梳的紋絲不亂的頭發(fā)上帘皿,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音畸陡,去河邊找鬼鹰溜。 笑死,一個胖子當著我的面吹牛丁恭,可吹牛的內(nèi)容都是我干的曹动。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼牲览,長吁一口氣:“原來是場噩夢啊……” “哼墓陈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贡必,失蹤者是張志新(化名)和其女友劉穎兔港,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仔拟,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡衫樊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了利花。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片科侈。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖炒事,靈堂內(nèi)的尸體忽然破棺而出臀栈,到底是詐尸還是另有隱情,我是刑警寧澤羡洛,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布挂脑,位于F島的核電站,受9級特大地震影響欲侮,放射性物質(zhì)發(fā)生泄漏崭闲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一威蕉、第九天 我趴在偏房一處隱蔽的房頂上張望刁俭。 院中可真熱鬧,春花似錦韧涨、人聲如沸牍戚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽如孝。三九已至,卻和暖如春娩贷,著一層夾襖步出監(jiān)牢的瞬間第晰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工彬祖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留茁瘦,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓储笑,卻偏偏與公主長得像甜熔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子突倍,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容