如何存储功能链的数据?

2 javascript functional-programming list object chain

一个简单的功能如下:

const L = a => L;
Run Code Online (Sandbox Code Playgroud)

形式

L
L(1)
L(1)(2)
...
Run Code Online (Sandbox Code Playgroud)

这似乎形成一个列表,但实际数据根本不存储,所以如果需要存储数据,例如[1,2],完成任务的最聪明的做法是什么?

const L = (a) => {
 // do somthing
  return L;
};
Run Code Online (Sandbox Code Playgroud)

我更喜欢这种简洁的箭头功能样式,并且不希望尽可能地破坏外部结构.当然,我理解一些外部结构修改是必需的,但我很好奇什么是可能的,特别是在功能风格而不是OO.

该规范仅用于存储功能链的数据.

有任何想法吗?谢谢.

最初最简单的方法是:

const L = (a) => {
  L.val = a;
  return L;
};
L.val = L;
Run Code Online (Sandbox Code Playgroud)

可以做一些,但没有数据积累.

{ [Function: L] val: [Circular] }
{ [Function: L] val: 1 }
{ [Function: L] val: 2 }
Run Code Online (Sandbox Code Playgroud)

注意:

每个列表应该独立于积累.

L(3)(4)
Run Code Online (Sandbox Code Playgroud)

将返回[3,4][2,3,3,4]与之前累积的其他列表.

高级主题!

如何存储Monoidal List功能链的数据?

Tha*_*you 5

函数currying和variadic参数并没有真正协同工作.一旦您意识到以下两个表达式不兼容,这是一个明显的限制

L (1)     -> [ 1 ]
L (1) (2) -> [ 1, 2 ]
Run Code Online (Sandbox Code Playgroud)

上面L (1)返回一个列表,但在第二个表达式中,我们希望L (1)是一个我们可以应用的函数2.L (1)可以是列表,也可以是生成列表的函数; 它不可能同时出现.

这就是为什么其他人提出.list了让实际价值得以实现的原因.您可以这样做,但知道使用对象属性或依赖突变是不必要的.您可以使用您选择的任何信号

const L = (x, acc = []) =>
  x === undefined
    ? acc
    : y => L (y, [...acc, x])
    
console.log
  ( L ()              // []
  , L (1) ()          // [ 1 ]
  , L (1) (2) ()      // [ 1, 2 ]
  , L (1) (2) (3) ()  // [ 1, 2, 3 ]
  )
Run Code Online (Sandbox Code Playgroud)

我们可以通过使用辅助辅助函数来抽象出可选参数.这种技术类似于您找到的解决方案,但在这里我们避免将值分配给函数属性,而是使用简单变量和非变异操作

const L = init =>
{ const loop = (acc, x) =>
    x === undefined
      ? acc
      : y => loop ([...acc, x], y)
  return loop ([], init)
}

console.log
  ( L ()              // []
  , L (1) ()          // [ 1 ]
  , L (1) (2) ()      // [ 1, 2 ]
  , L (1) (2) (3) ()  // [ 1, 2, 3 ]
  )
Run Code Online (Sandbox Code Playgroud)

或者看到您的要求有些灵活,通过更灵活的编码获得创意

const List = x =>
  k => k (x)
  
const append = x => xs =>
  List ([ ...xs, x ])

const prepend = x => xs =>
  List ([ x, ...xs ])
  
List ([]) (append (1)) (console.log)
// [ 1 ]

List ([ 2, 3 ]) (append (4)) (append (5)) (prepend (1)) (console.log)
// [ 1, 2, 3, 4, 5 ]
Run Code Online (Sandbox Code Playgroud)

将JavaScript的许可语法推向极限是很有趣的,但是使用扩展参数可以最好地定义可变参数函数

const L = (...values) =>
  values

console.log
  ( L ()         // []
  , L (1)        // [ 1 ]
  , L (1, 2)     // [ 1, 2 ]
  , L (1, 2, 3)  // [ 1, 2, 3 ]
  )
Run Code Online (Sandbox Code Playgroud)

一个不太人为的例子展示了一个更好的用例

const max = (x, ...ys) =>
  ys.length === 0
    ? x
    : max2 (x, max (...ys))
    
const max2 = (x, y) =>
   x > y ? x : y
   
console.log
  ( max (1, 5, 3)     // 5
  , max (5, 2, 9, 7)  // 9
  , max (4)           // 4
  , max ()            // undefined
  )
Run Code Online (Sandbox Code Playgroud)

  • 这真的是我见过的最精彩的回应之一.从你的帖子中可以学到很多东西,实际上我会感激地学习和玩耍.事实上,这个话题对我来说已经有一段时间了,但我可以用某种方式管理我觉得根本没有优化.我真诚的感谢 (3认同)