【问题标题】:Is foldRight equivalent to foldLeft given a noncommutative associative operation?foldRight 是否等同于 foldLeft 给定非交换关联操作?
【发布时间】:2023-03-30 00:41:01
【问题描述】:

在线课程中指出foldLeftfoldRight 对于关联和交换的运算符是等价的。

其中一位学生坚持认为此类运算符只需要具有关联性即可。所以这个属性对于像函数组合和矩阵乘法这样的操作应该是正确的。

据我所知,非可交换的关联运算不会为 foldLeftfoldRight 产生相同的结果,除非 z 是中性的,并且运算的累积方式使得操作数保持不变。在一般情况下,IMO 操作必须是可交换的。

list.foldLeft(z)(operation) == list.foldRight(z)(operation)

那么,为了使foldLeftfoldRight 等价,operation 应该同时具有关联性和可交换性,还是 operation 具有关联性就足够了?

【问题讨论】:

    标签: scala fold equivalent


    【解决方案1】:

    String 连接 ("abc" + "xyz") 是关联的,但不是可交换的,foldLeft/foldRight 会将初始/零元素放置在结果字符串的两端。如果那个零元素不是空字符串,那么结果就不同了。

    【讨论】:

      【解决方案2】:

      函数必须是可交换的和关联的。

      如果我们的函数是f,我们的元素是x1x4,那么:

      foldLeft 是f(f(f(x1, x2), x3), x4)

      foldRight 是f(x1, f(x2, f(x3, x4)))

      让我们使用平均函数,它是可交换的但不是关联的((a + b) / 2 == (b + a) / 2):

      scala> def avg(a: Double, b: Double): Double = (a + b) / 2
      avg: (a: Double, b: Double)Double
      
      scala> (0 until 10).map(_.toDouble).foldLeft(0d)(avg)
      res4: Double = 8.001953125
      
      scala> (0 until 10).map(_.toDouble).foldRight(0d)(avg)
      res5: Double = 0.9892578125
      

      编辑:我错过了仅关联与仅交换的船。请参阅@jwvy 的字符串连接示例,了解关联但非交换函数。

      【讨论】:

      • 好收获。将引用@jwvh 的字符串连接。
      【解决方案3】:

      foldLeft 是(...(z op x1)... op xn) foldRight 是x1 op (x2 op (... xn op z)...) 所以op 需要是可交换的和关联的,以使两者在一般情况下是等价的

      【讨论】:

        【解决方案4】:

        至少有三个相关案例有不同的答案:

        1. op: (B, A) -> Bop: (A, B) -> B 的一般情况下,如foldLeftfoldRight 的签名中,既没有定义关联性也没有定义交换性。

        2. 如果B >: Azop: (B, B) -> B 的两侧身份,而op关联,那么对于所有L 类型的@ 987654330@、L.foldLeft(z)(op) 返回的结果与L.foldRight(z)(op) 相同。

          这与以下事实密切相关:如果B >: Aop: (B, B) -> B,则如果op 是关联的,则对于所有List[A] 类型的LL.reduceLeft(op) 返回与L.reduceRight(op) 相同的结果。

        3. 如果B >: Aop: (B, B) -> B关联和交换,那么对于List[A] 类型的所有Lz 类型的zL.foldLeft(z)(op) 返回结果与L.foldRight(z)(op) 相同。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-06-12
          • 1970-01-01
          • 1970-01-01
          • 2011-09-09
          • 2017-03-25
          • 2017-11-04
          • 1970-01-01
          相关资源
          最近更新 更多