【发布时间】:2021-02-19 04:51:04
【问题描述】:
问题:
我正在学习函数式编程
开个玩笑,但也...
我有一个辅助函数,它一遍又一遍地与自己组合一个函数,直到满足某些条件。像 f(f(f(f(f(f(f(x))))))) 或 compose(f,f,f,f,f,f,f)(x) 一样,除非被告知停止,否则它会继续运行。
按照我实现它的方式,它真的不像是合成(无论如何,这可能是在这里使用的错误词)
这是我目前的解决方案:
const selfComposeWhile = curry(
(pred, fn, init) => {
let prevVal = null;
let nextVal = init;
while(prevVal == null || pred(prevVal, nextVal)){
prevVal = nextVal;
nextVal = fn(nextVal);
}
return nextVal;
}
);
这里正在使用:
const incOrDec = ifElse(gt(30), inc, dec);
console.log(
selfComposeWhile(lt, incOrDec, 0)
); // -> 29
我不想使用递归,因为 JavaScript 没有适当的尾递归,而且这个网站的同名(堆栈溢出)是我如何使用它的一个真正问题。
它没有任何错误,但我一直在尝试通过将函数式编程技术应用于一个虚拟问题来学习它们,这是我的代码明显脱颖而出的少数几个地方之一势在必行。
我也有
useWith(selfComposeWhile, [pipe(nthArg(1), always)]);
这需要一个只与 nextVal 相关的谓词,这似乎是更一般的情况。
问题:
谁能想到一种更实用(无递归)的方式来编写selfComposeWhile 及其表亲?
【问题讨论】:
-
@ScottSauyet 我注意到很多名称/命名约定只要稍加思考就可以理解,但我不会想到用它们搜索 Docs/Google。也许是没有数学背景的部分缺点。
-
我创建了这个库并参与了几乎所有的命名决定,但我仍然有一些无法理解,或者他们的名字并不总是有意义的。
fold/unfold一听就明白了,until的名字也很好。但是想出它们,或者理解assoc或juxt需要更多的努力。我不知道任何解决方案。
标签: javascript ramda.js