为什么函数组合在Javascript中从右到左组成?

5 javascript functional-programming associative composition function-composition

功能组合从右到左组成:

const comp  = f => g => x => f(g(x));
const inc = x => x + 1;
const dec = x => x - 1;
const sqr = x => x * x;
let seq = comp(dec)(comp(sqr)(inc));

seq(2); // 8
Run Code Online (Sandbox Code Playgroud)

seq(2)转换为dec(sqr(inc(2)))和应用程序顺序inc(2)...sqr...dec.因此,函数按照传递给它们的相反顺序调用comp.这对于Javascript程序员来说并不直观,因为他们习惯于从左到右的方法链接:

o = {
  x: 2,
  inc() { return this.x + 1, this },
  dec() { return this.x - 1, this },
  sqr() { return this.x * this.x, this }
}

o.dec().sqr().inc(); // 2
Run Code Online (Sandbox Code Playgroud)

我认为这令人困惑.这是一个颠倒的构成:

const compl = f => g => x => g(f(x));
let seql = compl(dec)(compl(sqr)(inc));

seql(2); // 2
Run Code Online (Sandbox Code Playgroud)

功能组合从右到左有什么原因吗?

小智 5

回答原来的问题:为什么功能组成从右到左组成?

  1. 所以它传统上是用数学制作的
  2. comp(f)(g)(x) 与...有相同的顺序 f(g(x))
  3. 创建反向或正向组合是微不足道的(参见示例)

前向功能组成:

const flip = f => x => y => f(y)(x);
const comp = f => g => x => f(g(x));
const compl = flip(comp);

const inc = x => x + 1;
const sqr = x => x * x;

comp(sqr)(inc)(2); // 9
compl(sqr)(inc)(2); // 5
Run Code Online (Sandbox Code Playgroud)

flip 在这方面,限制了翻转的组合物不能与其自身组合以形成"更高阶的组合物":

const comp2 = comp(comp)(comp);
const compl2 = compl(compl)(compl);
const add = x => y => x + y;

comp2(sqr)(add)(2)(3); // 25
compl2(sqr)(add)(2)(3); // nonsense
Run Code Online (Sandbox Code Playgroud)

结论:从右到左的顺序是传统的/传统的,但不直观.


FPs*_*ent 3

您的问题实际上是关于函数组合运算符定义中参数的顺序,而不是右关联性或左关联性。在数学中,我们通常写“fo g”(相当于定义中的 comp(f)(g))来表示接受 x 并返回 f(g(x)) 的函数。因此,“fo (goh)”和“(fog) o h”是等价的,都表示将每个参数 x 映射到 f(g(h(x))) 的函数。

也就是说,我们有时会写 f;g (相当于代码中的 compl(f)(g))来表示将 x 映射到 g(f(x)) 的函数。因此,(f;g);h 和 f;(g;h) 都表示将 x 映射到 h(g(f(x))) 的函数。

参考: https: //en.wikipedia.org/wiki/Function_composition#Alternative_notations