還記得 Haskell Curry嗎,java
多巧啊, 人家姓 Curry 名 Haskell, 難怪 Haskell 語言會自動柯里化, 呵呵. 可是不奇怪嗎, 爲何要柯里化呢. 爲何如此重要致使 Haskell 會默認自動柯里化全部函數, 不就是返回一個部分配置好的函數嗎.git
咱們來看一個 Haskell 的代碼.github
結果都是4, 這有設麼用呢.數組
這裏看不出來, 放到高階函數
試試. 什麼? 看不懂天書 Haskell, 來看看 JavaScript 吧.函數
咱們來解一個問題
1. 寫一個函數, 能夠鏈接字符數組, 如 f(['1','2']) => '12'
好吧,若是不用柯里化, 怎麼寫? 啊哈 reduce
spa
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