lodash流程功能是真正的组合功能,还是看起来像是一个功能,但是经过优化可以快速运行并牺牲我期望的灵活性?我希望flow能够返回一个我可以进行curry的函数,但是它返回了一个使用Javascript"的arguments关键字的函数。因此,咖喱不能告诉有待处理的参数,而且它会立即被调用。
足够直观地工作:
var add = function(x, y) {
return x + y
};
var exclam = function(x) {
return x.toString() + "!";
}
exclam(1) // "1!"
add(1,2) // 3
var add1 = FP.curry(add)(1);
add1(4) // 5
var add1AndExclam = FP.flow([add1, exclam])
add1AndExclam(2) // "3!"
非直观的结果:
addAndExclam = FP.flow([add, exclam])
/*
function(){
var t=arguments,e=t[0];
if(i&&1==t.length&&yi(e)&&e.length>=200)return i.plant(e).value();
for(var u=0,t=r?n[u].apply(this,t):e;++u<r;)t=n[u].call(this,t);
return t
}
*/
addAndExclam(1,2) // "3!"
add1AndExclamV2 = FP.curry(addAndExclam)(1) // "NaN!"`
寻找另一个库以帮助函数式编程范例是否过度?我应该掀起自己的作品吗?我使用了lodash因为它已经在我的项目中了。文档使得流程看起来应该是lodash的撰写。
我还发现很难在lodash的每一个中讨论数据参数(我想要像eachMyArrayName快捷方式一样)。我是使用curryRight还是使用lodash对象占位符约定。
lodash FP是否仅仅是为了使lodash功能自动化?或者我做错了什么,它可以用作主要的函数式编程助手?
编辑:
如果我想,我可以像这样包装这个函数,但它似乎打败了元编程的目的,以获得样板代码。
add1AndExclamV2 = FP.curry(function(x, y) {
return addAndExclam(x, y)
})(1)
add1AndExclamV2(2)
&#34;!3&#34;`
答案 0 :(得分:0)
var myAdd = function(x, y) { return x + y; };
var exclam = function(x) { return x.toString() + '!'; };
var addSclam = pipe(myAdd, exclam);
addSclam(1,2); // "3!"
var add1Sclam = curry( addSclam )(1);
add1Sclam(500); // "501!"
看起来ramda对我来说很直观。它为我的项目增加了另外1.2mb,但我想它可以用来或多或少取代lodash。
答案 1 :(得分:0)
这只是基本的功能构成。 Lodash&#34; flow&#34;和Rambda&#34; pipe&#34;可能发现很难命名这些功能,因为它们不是通用的。他们不是真实的&#34;与在短语&#34;真正的撰写函数&#34;中使用 real 这个词的方式相同。
您可以使用comp2
使用一元函数编写二元函数 - catch是&#34; binary&#34;函数必须是curry形式而不是取元组
let f = x => y => ...
而不是
let f = (x,y) => ...
回想一下,函数式编程的根源在于the lambda calculus,其中没有一个函数除了1参数之外还有其它东西。
const curry = f => x => y => f (x,y)
const comp = f => g => x => f (g (x))
const comp2 = comp (comp) (comp)
var add = function(x, y) { return x + y };
var exclam = function(x) { return x.toString() + "!"; }
console.log(exclam (1)) // "1!"
console.log(add (1,2)) // 3
var add1 = curry (add) (1)
console.log(add1 (4)) // 5
var addAndExclam = comp2 (exclam) (curry (add))
console.log(addAndExclam (1) (2)) // "3!"
&#13;
我鼓励您使用substitution model来查看表达式的评估方式
将所有类型放在一起可以帮助您更有效地推理该计划
// curry :: ((a,b) -> c) -> a -> b -> c
const curry = f => x => y => f (x,y)
// comp :: (b -> c) -> (a -> b) -> (a -> c)
const comp = f => g => x => f (g (x))
// comp2 :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)
const comp2 = comp (comp) (comp)
// add :: (Number,Number) -> Number
var add = function(x, y) { return x + y };
// exclam :: Number -> String
var exclam = function(x) { return x.toString() + "!"; }
console.log(exclam (1)) // "1!"
console.log(add (1,2)) // 3
// add1 :: Number -> Number
var add1 = curry (add) (1)
console.log(add1 (4)) // 5
// addAndExlam :: Number -> Number -> String
var addAndExclam = comp2 (exclam) (curry (add))
console.log(addAndExclam (1) (2)) // "3!"
关于你的评论:
我想如果我想编写一个特殊的函数,其中一个嵌套函数有两个args,我会把它写出来
好主意。如果您发现自己四处寻找内置程序(由您的语言或某些库提供),那么您应该首先尝试将其写出来。至少要确认自己是否正确理解了自己的需求。
这是完全可以接受的
const addAndExclam = (x,y) => exclam (add (x,y))
这是
const addAndExclam = x => y => exclam (add (x,y))
如果您稍后了解comp2
并看到它可以更好地描述代码,那么您可以在那时实现它
const addAndExclam = comp2 (exclam) (curry (add))