纯函数javascript中的预计算值
我有这样的代码:纯函数javascript中的预计算值,javascript,optimization,functional-programming,Javascript,Optimization,Functional Programming,我有这样的代码: let createArray = (A) => A.map((val) => val * heavyFn(A.length) ) 其中,heavyFn(X)是一个消耗资源的函数,它为常数X返回的值总是相同的。我相信像Haskell这样的好函数语言会对此进行优化,所以对于每个结果,heavyFn(X)只调用一次,但javascript显然不会 我可以这样优化它: let createArray = (A) => { const H = h
let createArray = (A) =>
A.map((val) =>
val * heavyFn(A.length)
)
其中,heavyFn(X)
是一个消耗资源的函数,它为常数X返回的值总是相同的。我相信像Haskell这样的好函数语言会对此进行优化,所以对于每个结果,heavyFn(X)
只调用一次,但javascript显然不会
我可以这样优化它:
let createArray = (A) => {
const H = heavyFn(A.length);
return A.map((val) =>
val * H
)
}
但是有可能用纯函数式javascript编码吗?我的意思是没有变量,只有参数,没有显式返回,没有花括号,只有嵌套的箭头函数表达式。只是出于好奇,javascript是否具有功能性
我知道的唯一办法是
let createArray = A => [heavyFn(A.length), ...A].map((val,i,H) =>
val * H[0]
).slice(1)
但这看起来像是一次黑客攻击。你可以用生命来结束沉重的生活
let createArray = (A) =>
(heavy => A.map((val) => val * heavy))
(heavyFn(A.length));
使用curried函数:
constmult=x=>y=>x*y;
const createArray=A=>A.map(mult(heavyFn(A.length));
或者,您可以使用本地绑定。不幸的是,JS只提供了let
作为声明语句。同样,您可以使用以下组合器模拟本地绑定const\u let=f=>f()
。像一样使用它((x=2;y=x*2;z=y*2)=>x+y+z)
。正如您所见,\u让
使用默认参数,并允许名称依赖于以前声明的参数。我认为Haskell不必对此进行优化(如果是这样,这是优化器的一个实现细节)。但是要知道,在纯函数式编程中,本地绑定并没有错。你更可能寻找的术语是无意义的,而不是纯粹的。(顺便说一句,给定\a->map(\val->val*长度a)a
,吐出map=@phipsgabler你是对的。我认为延迟求值本身会导致共享,但即使我将heavyFn
和传递给map
的lambda都包装在一个中,heavyFn
仍会在每次迭代时重新调用。因此函数必须与其主体内联,这是完全合理的,但仍然是一个特定的优化。