from http://oyanglul.us
多巧啊, 人家姓 Curry 名 Haskell, 难怪 Haskell 言语会自动柯里化, 呵呵. 然则不新鲜吗, 为何要柯里化呢. 为何云云主要致使 Haskell 会默许自动柯里化一切函数, 不就是返回一个部份设置好的函数吗.
我们来看一个 Haskell 的代码.
max 3 4 (max 3) 4
效果都是4, 这有设么用呢.
这里看不出来, 放到高阶函数
尝尝. 什么? 看不懂天书 Haskell, 来看看 JavaScript 吧.
我们来解一个题目
1. 写一个函数, 能够衔接字符数组, 如 f(['1','2']) => '12'
好吧,假如不必柯里化, 怎样写? 啊哈 reduce
var concatArray = function(chars){ return chars.reduce(function(a, b){ return a.concat(b); }); } concat(['1','2','3']) // => '123'
很简单,对吧.
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
就不能同时处置惩罚加, 乘和减? 那末怎样能把他提取出来呢? 来对比下柯里化的解法.
柯里化函数接口
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 + ''
})
view raw
why-curry-helps.md hosted with ❤ by
GitHub