javascript - 如何存储功能链的数据?

标签 javascript list object functional-programming chain

下面是一个简单的函数:

const L = a => L;

表格

L
L(1)
L(1)(2)
...

这似乎形成了一个列表,但根本没有存储实际数据,所以如果需要存储 [1,2] 之类的数据,最聪明的做法是让任务完成了吗?

const L = (a) => {
 // do somthing
  return L;
};

我更喜欢这种简洁的箭头函数风格,尽量不破坏外部结构。当然,我知道需要对外部结构进行一些修改,但我很好奇什么是可能的,尤其是在函数式风格而不是 OO 中。

规范只是存储函数链的数据。

有什么想法吗?谢谢。

最初最简单的方法是:

const L = (a) => {
  L.val = a;
  return L;
};
L.val = L;

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

{ [Function: L] val: [Circular] }
{ [Function: L] val: 1 }
{ [Function: L] val: 2 }

注意事项:

每个列表都应该独立进行累加。

L(3)(4)

将返回 [3,4] 而不是 [2,3,3,4] 并预先积累另一个列表。

进阶话题!

How to store data of a functional chain of Monoidal List?

最佳答案

函数柯里化(Currying)和可变参数实际上不能一起工作。一旦您意识到以下两个表达式不兼容,这是一个显而易见的限制

L (1)     -> [ 1 ]
L (1) (2) -> [ 1, 2 ]

上面的 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 ]
  )

我们可以使用辅助辅助函数抽象出可选参数。这种技术类似于您找到的解决方案,但在这里我们避免了笨拙的函数属性赋值,而是使用简单的变量和非变异操作

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 ]
  )

或者看到你的要求有点灵活,用更灵活的编码来发挥创意

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 ]

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

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

console.log
  ( L ()         // []
  , L (1)        // [ 1 ]
  , L (1, 2)     // [ 1, 2 ]
  , L (1, 2, 3)  // [ 1, 2, 3 ]
  )

一个不那么做作的例子演示了一个更好的用例

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
  )

关于javascript - 如何存储功能链的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51279085/

相关文章:

Javascript:将参数传递给函数以调用变量

javascript - 如何在 Vue.js 中的模板元素中进行字符串插值?

C# Linq 在另一个 List<int> 中查找 List<int> 中项目的所有索引

python - 根据条件反转python中的列表

python - 为什么 re.groups() 不为我的一个正确匹配的组提供任何东西?

javascript - 使用 typescript 点击删除 Canvas 元素

javascript - 需要什么样的命令行来查找所有信用卡号的总和并按升序排列它们?

python - 发出附加字典到列表的问题

javascript - 将变量同时用作函数和对象实例

javascript - 使用参数对象将用户生成的值作为参数传递给函数时遇到问题