为什么我在使用 transduce 时会出错?

Why do I get an error when I use transduce?

我对函数式编程还是个新手,一直在努力学习如何使用转换器。我以为我有一个很好的用例,但每次我尝试用 Ramda 为它编写一个传感器时,我都会收到以下错误:

reduce: list must be array or iterable

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

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)

在换能器的上下文中,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>

顺序颠倒的原因是换能器利用了 属性 函数组合,有时称为元数抽象。它只是意味着一个函数组合可以return,嗯,另一个函数:

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

为什么return组合另一个函数?因为 map 是一个二元函数,它需要一个函数参数作为它的第一个参数。因此,当对组合进行评估时,它会产生另一种由两个部分应用的 map 组成的组合。正是这个额外的迭代颠倒了顺序。我就此打住,没有说明评估步骤,因为我认为否则会变得太复杂。

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