scala - 了解传入折叠的 curry 函数

标签 scala fold monoids

我无法理解 this Scala 中 Book FP 中的代码。这是代码:

trait Monoid[A] {
  def op(a1: A, a2: A): A
  def zero: A
}

def endoMonoid[A]: Monoid[A => A] = new Monoid[A => A] {
    def op(f: A => A, g: A => A) = f compose g
    val zero = (a: A) => a
}

def foldMap[A, B](as: List[A], m: Monoid[B])(f: A => B): B =
  as.foldLeft(m.zero)((b, a) => m.op(b, f(a)))

// The function type `(A, B) => B`, when curried, is `A => (B => B)`.
  // And of course, `B => B` is a monoid for any `B` (via function composition).
def foldRight[A, B](as: List[A])(z: B)(f: (A, B) => B): B =
    foldMap(as, endoMonoid[B])(f.curried)(z)
foldMap期待一个函数 f: A => B .

foldRight , 当 f curry 你有A => (B => B) ,所以我想f.curried正在工作,因为它与 (A => B => B) 相同, 所以 foldRight正在传递给 foldMap它期望什么(类型为 A => B 的函数),然后,接下来发生的是 foldMap被调用并返回一个函数 B => B , 那就是 z(f.curried)(z) 中发挥作用你调用函数B => B带有参数 z获得最终 B .

我对吗?对我来说,推理这段代码有点复杂。

注意:这里是 scalafiddle如果你想玩它。

最佳答案

好吧,你对我来说似乎很全面。不过,我要澄清几点:

  • 我宁愿说“所以我想 f.curried 正在工作,因为 A => (B => B) (A => B => B) 相同”( 在这里模棱两可你说的是 f.curried 结果类型基本上,而不是 z )
  • 我宁愿在这里加一个点而不是逗号:“foldMap 期待一个函数 f: A => B 。在 foldRight, ... ”以及几乎所有其他地方。更短的短语,更清晰的解释。
  • 可能是什么错误,(什么让您感到困惑?)是 (f.curried)(z)不能单独工作,也不会在 foldMap(as, endoMonoid[B]) 之后调用.这是第一个foldMap(as, endoMonoid[B])(f.curried)这被称为然后(z) .第一个返回 B => B并调用第二个返回 B .
  • 关于scala - 了解传入折叠的 curry 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55828508/

    相关文章:

    sql - Spark SQL : Cache Memory footprint improves with 'order by'

    scala - 在 Spark 和 Scala 中创建数据集时出现问题

    java - 如何检查 Java 代码中的 Scala Option 类型是否为 None

    haskell - MonadPlus IO 不是幺半群

    haskell - 不理解 Monoid 定义中态射的表示法

    unit-testing - 如何编写确保编译失败的 Scala 单元测试?

    f# - 如何在 F# 中实现 “efficient generalized fold”?

    java - 应该如何连接数组流?

    list - Haskell 中列表的递归

    haskell - 为什么 GHC 不能为 Monoid 派生实例?