Javascript 拉姆达沉着冷静 问题是:

Javascript 拉姆达沉着冷静 问题是:,javascript,ramda.js,Javascript,Ramda.js,我在学习函数式编程 只是开玩笑,但也。。。 我有一个helper函数,它一次又一次地与自身组成一个函数,直到满足某些条件。类似于f(f(f(f(f(f(f(x))))))或组合(f,f,f,f,f,f,f)(x),除非它继续运行,除非被告知停止 按照我实现它的方式,它并不像是真正的合成(不管怎么说,这里使用这个词可能是错误的) 这是我当前的解决方案: const selfComposeWhile=curry( (pred,fn,init)=>{ 设prevVal=null; 设nextVal=i

我在学习函数式编程

只是开玩笑,但也。。。 我有一个helper函数,它一次又一次地与自身组成一个函数,直到满足某些条件。类似于
f(f(f(f(f(f(f(x))))))
组合(f,f,f,f,f,f,f)(x)
,除非它继续运行,除非被告知停止

按照我实现它的方式,它并不像是真正的合成(不管怎么说,这里使用这个词可能是错误的)

这是我当前的解决方案:

const selfComposeWhile=curry(
(pred,fn,init)=>{
设prevVal=null;
设nextVal=init;
while(prevVal==null | | pred(prevVal,nextVal)){
prevVal=nextVal;
nextVal=fn(nextVal);
}
返回nextVal;
}
);
现在正在使用:

const incOrDec=ifElse(gt(30),inc,dec);
console.log(
自合成时间(lt、incOrDec、0)
); // -> 29
我不想使用递归,因为JavaScript没有适当的尾部递归,而这个站点的同名者(堆栈溢出)是我如何使用它的真正问题

它没有任何错误,但我一直在尝试通过将函数式编程技术应用于一个虚拟问题来学习函数式编程技术,这是我的代码中为数不多的几个绝对必要的地方之一

我也有

与(selfComposeWhile,[pipe(nthArg(1),始终)])一起使用;
这需要一个只与nextVal有关的谓词,这似乎是更一般的情况

问题是:
有谁能想出一种更实用的(无递归)方法来编写
selfComposeWhile
及其近亲吗?

R.unfold主要做你想做的事情,它接受一个种子值(
init
),并对其进行转换,每次迭代它都返回当前值和新的种子值。在每次迭代中,您需要决定继续或停止使用谓词

函数和R.unfold之间的主要区别在于,最后一个函数生成一个数组,这可以通过R.last轻松解决:

const{curry,pipe,unfold,last}=R
const selfComposeWhile=咖喱(
(pred,fn,init)=>管道(
展开(n=>pred(n,fn(n))&[n,fn(n)],
最后的
)(初始化)
)
常数{ifElse,gt,inc,dec,lt}=R
常量incOrDec=ifElse(gt(30),inc,12月)
console.log(selfComposeWhile(lt,incOrDec,0))/->29

R.unfold主要做您想做的事情,它接受一个种子值(
init
),并对其进行转换,在每次迭代中返回当前值和新的种子值。在每次迭代中,您需要决定继续或停止使用谓词

函数和R.unfold之间的主要区别在于,最后一个函数生成一个数组,这可以通过R.last轻松解决:

const{curry,pipe,unfold,last}=R
const selfComposeWhile=咖喱(
(pred,fn,init)=>管道(
展开(n=>pred(n,fn(n))&[n,fn(n)],
最后的
)(初始化)
)
常数{ifElse,gt,inc,dec,lt}=R
常量incOrDec=ifElse(gt(30),inc,12月)
console.log(selfComposeWhile(lt,incOrDec,0))/->29
我现在确定的解决方案。 我将selfComposeWhile命名为
unfoldUntil
。我不确定这是不是最好的名字,因为它不会返回列表。它基本上是
R.until
,谓词可以访问上一个和下一个值

为了使它们更加协调一致,我将我的
while
行为更改为
until
行为(
R.complete
谓词)


展开直到 如果已键入:

展开直到:(
pred:(p:T,n:T)=>布尔值,
fn:(a:T)=>T,
init:T
)=>T
实施

const=curry(
(pred,fn,init)=>管道(
展开(n=>
isNil(n)?
错误:
呼叫((下一个=fn(n))=>
(pred(n,next)?
[下一步,空]:
[下一步,下一步])
)
),
最后的
)(初始化)
);
注意:这将永远不会将null/undefined传递到转换函数(
fn
)。可以使用返回null作为停止条件并返回上一个值的转换。否则,将返回导致谓词返回true的
next
的第一个值。

我现在确定的解决方案。 我将selfComposeWhile命名为
unfoldUntil
。我不确定这是不是最好的名字,因为它不会返回列表。它基本上是
R.until
,谓词可以访问上一个和下一个值

为了使它们更加协调一致,我将我的
while
行为更改为
until
行为(
R.complete
谓词)


展开直到 如果已键入:

展开直到:(
pred:(p:T,n:T)=>布尔值,
fn:(a:T)=>T,
init:T
)=>T
实施

const=curry(
(pred,fn,init)=>管道(
展开(n=>
isNil(n)?
错误:
呼叫((下一个=fn(n))=>
(pred(n,next)?
[下一步,空]:
[下一步,下一步])
)
),
最后的
)(初始化)
);

注意:这将永远不会将null/undefined传递到转换函数(
fn
)。可以使用返回null作为停止条件并返回上一个值的转换。否则,将返回导致谓词返回true的
next
的第一个值。

Wow。完美的我知道这感觉像是我不能独自一人想要的东西,很高兴看到拉姆达基本上内置了它啊,每次展开两次f(n)。但要解决这个问题并不难。再次感谢:)哇。完美的我知道这感觉像是我不能独自一人想要的东西,很高兴看到拉姆达基本上内置了它啊,每次展开两次f(n)。但要解决这个问题并不难。再次感谢:)请注意与的相似之处。不会的