函數式編程之Compose

Compose基本概念

顧名思義,在函數式編程中,Compose 就是將幾個有特色的函數拼湊在一塊兒, 讓它們結合, 產生一個嶄新的函數,以下就是組合react

const compose = (f,g) => (...arg) => f(g(...arg))git

f跟g在如上都是函數,...arg是在他們之間經過管道(pipe)傳輸的值github

讓咱們來嘗試使用一下組合編程

let toUpperCase = (x) => x.toUpperCase();
let exclaim = (x) => x + '!';
let shout = compose(toUpperCase,exclaim);
shout('hello world')
// HEELO WORLD !複製代碼

pointfree 模式

pointfree模式指的是,永遠沒必要說出你的數據,它的意思是指函數無須說起將要操做的數據是什麼樣的,一等公民的函數,curry 以及compose 協做起來很是有助於實現這種模式redux

// 非 pointfree, 由於提到了數據 word
let snakeCase = (word) => word.toUpperCase().replace(/\s+/ig,'-');
// pointfree
let snakeCase = compose(replace(/\s+/ig,'-'),toUpperCase)複製代碼

pointfree 模式可以幫助咱們減小沒必要要的命名,讓代碼保持簡潔和通用。對函數式代碼來講,pointfree 是很是好的石蕊試驗,由於它能告訴咱們一個函數是不是接受輸入返回輸出的小函數。數組

一些問題

回到樓上,咱們能夠看到上面的compose示例都只是傳入了兩個函數,由於咱們的compose實現也只支持兩個函數,那麼若是咱們想要支持一條很長很長的管道的時候,顯然上面的compose就不夠用了,下面咱們能夠來看看redux是如何實現compose的bash

// 摘自 https://github.com/reactjs/redux/blob/master/src/compose.js
export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }
  if (funcs.length === 1) {
    return funcs[0]
  }
  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}複製代碼

代碼很簡潔,利用了數組的reduce方法來處理,就這樣, 想拼多長就多長函數式編程

相關文章
相關標籤/搜索