纯函数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
仍会在每次迭代时重新调用。因此函数必须与其主体内联,这是完全合理的,但仍然是一个特定的优化。