【问题标题】:Why do I get an error when I use transduce?为什么我在使用 transduce 时会出错?
【发布时间】:2019-07-16 01:40:06
【问题描述】:

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

【问题讨论】:

    标签: functional-programming ramda.js transducer


    【解决方案1】:

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

    【讨论】:

    • 谢谢,它成功了。现在这是否意味着由于必须颠倒顺序,所以 transduce 以相反的顺序执行传感器?
    • 不,不是。计算将按照 compose 中表示的顺序运行。 compose 在转换器中被“反转”是有充分理由的,但我不记得了。我相信其他人会提供更多信息
    【解决方案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 是一个二进制函数,它需要一个函数参数作为它的第一个参数。因此,当评估组合时,它会产生另一个由两个部分应用的maps 组成的组合。正是这种额外的迭代颠倒了顺序。我停在这一点上,没有说明评估步骤,因为我认为否则它会变得太复杂。

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

    【讨论】:

      猜你喜欢
      • 2021-03-04
      • 2010-10-18
      • 2021-10-02
      • 2022-01-21
      • 2021-09-10
      • 2019-01-14
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多