Rad*_*dex 2 javascript functional-programming ecmascript-6
我正在学习JavaScript中的函数编程,目前我有以下代码.
我想将这两个函数组合在另一个函数中,该函数使用户通过一个值并使结果等于传递的值加上10乘以3使用以下函数.
伪代码示例:
const myFormulat= add(10).multiply(3);
Run Code Online (Sandbox Code Playgroud)
如何仅使用vanilla JS ES6编写此功能?
function add(x){
return function(y){
return y + x;
};
}
function multiply(x){
return function(y){
return y * x;
};
}
// my calculation
// get x add 10 and after multiply by 3
Run Code Online (Sandbox Code Playgroud)
熊陷阱和地雷
这个答案仅仅是为了证明为什么这不是一个好主意 - 复杂性通过屋顶基本没有收获.注意我们必须告诉我们的函数何时结束,所以我添加了一个特殊的函数,call所以我们的表达式将如下所示
.add(3).mult(4).call(x)
// where x is the input for the entire function chainRun Code Online (Sandbox Code Playgroud)
最后一个变化是我们的函数库add,mult等必须被包裹在一些范围限制我们代理的范围.该范围告诉我们我们希望链接的功能的确切位置.
哦,如果这部分的标题不够警告,我们也使用了Proxy.
// helpers
const identity = x => x
const comp = f => g => x => f(g(x))
// magic wand
const using = scope => {
let acc = identity
let p = new Proxy({
call: x => acc(x),
}, {
get: (target, name) => {
if (name in target)
return target[name]
else if (name in scope)
return x => {
acc = comp (scope[name](x)) (acc)
return p
}
else
throw Error(`${f} is not undefined in ${scope}`)
}
})
return p
}
// your functions wrapped in a scope
const math = {
add: x => y => x + y,
mult: x => y => x * y
}
// chain it up
const main = using(math).add(3).mult(4).add(5).mult(6).call
console.log(main(2))
// (((2 + 3) * 4) + 5) * 6
// ((5 * 4) + 5) * 6
// (20 + 5) * 6
// 25 * 6
// 150Run Code Online (Sandbox Code Playgroud)
功能构成
但严重的是,不要这样做..考虑到您的起点,通过操作员推送所有内容是不自然的,您应该寻找更有效的方法来组合功能.
我们可以使用稍微不同的表示法有效地做同样的事情 - 这里最大的区别是复杂度几乎为零
const compose = (f,...fs) => x =>
f === undefined ? x : compose (...fs) (f(x))
const add = x => y => x + y
const mult = x => y => x * y
const main = compose (add(3), mult(4), add(5), mult(6))
console.log(main(2)) // => 150Run Code Online (Sandbox Code Playgroud)
函子
也许你不喜欢传统的功能组合,这很好,因为我们还有另一种方法来解决使用Functors的问题- 简单地说,Functor是一个带有map函数的容器.
下面我们有一个Box函数,它将值放在我们的容器中.该map函数接受一个函数,并使用用户指定函数的返回值创建一个新Box.最后,我们有一个fold功能,让我们可以开箱即用
同样,它改变了我们编写代码的方式,但减少的复杂性是巨大的(与Proxy示例相比)
const Box = x => ({
map: f => Box(f(x)),
fold: f => f(x)
})
const add = x => y => x + y
const mult = x => y => x * y
const main = Box(2).map(add(3)).map(mult(4)).map(add(5)).map(mult(6)).fold
main(console.log) // 150Run Code Online (Sandbox Code Playgroud)