为什么在使用转导时出现错误?

时间:2019-07-16 01:40:06

标签: functional-programming ramda.js transducer

我还是函数编程的新手,并一直在尝试学习如何使用传感器。我以为我有一个很好的用例,但是每次尝试使用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)

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:2)

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

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的另一个合成。正是这种额外的迭代使顺序相反。在这一点上,我没有说明评估步骤,因为我认为否则会太复杂。

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