0

我对函数式编程仍然很陌生,并且一直在尝试学习如何使用传感器。我以为我有一个很好的用例,但每次我尝试用 Ramda 编写一个转换器时,我都会收到以下错误:

reduce:列表必须是数组或可迭代的

我尝试过几种方式重写它,并查看了转导网络上的几种解释,但无济于事。有什么建议么?

const data = [{cost:2,quantity:3},{cost:4,quantity:5},{cost:1,quantity:1}];
const transducer = R.compose(R.map(R.product), R.map(R.props(['cost', 'quantity'])));
const result = R.transduce(transducer, R.add, 0)(data);
console.log(result)
4

2 回答 2

3

在传感器的上下文中,compose从左到右读取。你只需要反转productprops

const data = [
  {cost:2,quantity:3},
  {cost:4,quantity:5},
  {cost:1,quantity:1}];
  
const transducer = 
  compose(
    map(props(['cost', 'quantity'])),
    map(product));

console.log(

  transduce(transducer, add, 0, data)

)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {compose, map, props, product, transduce, add} = R;</script>

于 2019-07-16T05:42:35.960 回答
2

顺序颠倒的原因是转换器利用了函数组合的特性,该特性有时被称为从 arity 中抽象出来。它只是意味着一个函数组合可以返回另一个函数:

const comp = f => g => x => f(g(x));

const mapTrace = tag => f => (console.log(tag), xs => (console.log(tag), xs.map(f)));

const sqr = x => x * x;

const main = comp(mapTrace("a")) (mapTrace("b")) (sqr); // returns another function

console.log(main); // logs the 2nd map and then the 1st one (normal order)

// pass an additional argument to that function

console.log(
  main([[1,2,3]])); // logs in reverse order

为什么返回组合另一个函数?因为map是一个二进制函数,它需要一个函数参数作为它的第一个参数。因此,当评估该组合物时,它会产生另一个由两个部分应用map的 s 组成的组合物。正是这种额外的迭代颠倒了顺序。我停在这一点上,没有说明评估步骤,因为我认为否则它会变得太复杂。

此外,您现在可以看到传感器如何将两个迭代融合在一起:它们只是使用函数组合。你能用手做吗?是的,你绝对可以做到这一点。

于 2019-07-16T06:51:17.837 回答