[gist]爲何要柯里化(curry)

from http://oyanglul.usjavascript

還記得 Haskell Curry嗎,java

多巧啊, 人家姓 Curry 名 Haskell, 難怪 Haskell 語言會自動柯里化, 呵呵. 可是不奇怪嗎, 爲何要柯里化呢. 爲何如此重要致使 Haskell 會默認自動柯里化全部函數, 不就是返回一個部分配置好的函數嗎.git

咱們來看一個 Haskell 的代碼.github

max 3 4
(max 3) 4

結果都是4, 這有設麼用呢.數組

這裏看不出來, 放到高階函數試試. 什麼? 看不懂天書 Haskell, 來看看 JavaScript 吧.函數

咱們來解一個問題

1. 寫一個函數, 能夠鏈接字符數組, 如 f(['1','2']) => '12'

好吧,若是不用柯里化, 怎麼寫? 啊哈 reducespa

var concatArray = function(chars){
  return chars.reduce(function(a, b){
    return a.concat(b);
  });
}
concat(['1','2','3']) // => '123'

很簡單,對吧.code

2. 如今我要其中全部數字加1, 而後在鏈接

var concatArray = function(chars, inc){
  return chars.map(function(char){
    return (+char)+inc + '';
  }).reduce(function(a,b){
      return a.concat(b)
  });
}
console.log(concatArray(['1','2','3'], 1))// => '234'

3. 全部數字乘以2, 再重構試試看

var multiple = function(a, b){
  return +a*b + ''
}
var concatArray = function(chars, inc){
  return chars.map(function(char){
    return multiple(char, inc);
  }).reduce(function(a,b){
      return a.concat(b)
  });
}
console.log(concatArray(['1','2','3'], 2)) // => '246'

是否是已經看出問題了呢? 若是我在須要每一個數字都減2,是否是很麻煩呢.須要將map 參數匿名函數中的 multiple 函數換掉. 這樣一來concatArray就不能同時處理加, 乘和減? 那麼怎麼能把他提取出來呢? 來對比下柯里化的解法.blog

柯里化函數接口

var multiple = function(a){
  return function(b){
    return +b*a + ''
  }
}

var plus = function(a){
  return function(b){
    return (+b)+a + ''
  }
}
var concatArray = function(chars, stylishChar){
  return chars.map(stylishChar)
    .reduce(function(a,b){
      return a.concat(b)
  });
}
console.log(concatArray(['1','2','3'], multiple(2)))
console.log(concatArray(['1','2','3'], plus(2)))

有什麼不同呢 1. 處理數組中字符的函數被提取出來, 做爲參數傳入 2. 提取成柯里化的函數, 部分配置好後傳入, 好處顯而易見, 這下接口很是通暢 不管是外層調用接口

concatArray(['1','2','3'], multiple(2))

仍是內部的 map 函數

chars.map(stylishChar)

這些接口都清晰了不少, 不是嗎

這就是函數式的思想, 用已有的函數組合出新的函數, 而柯里化每消費一個參數, 都會返回一個新的部分配置的函數, 這爲函數組合提供了更靈活的手段, 而且使得接口更爲流暢.

再加上自動柯里化的庫 ramda, 簡直就完美了

var multiple = ramda.curry(function(a, b){
  return +b*a + ''
})
var plus = ramda.curry(function(a, b){
  return (+b)+a + ''
})

JS Bin

view raw why-curry-helps.md hosted with ❤ by GitHub
相關文章
相關標籤/搜索