首页 > 解决方案 > 了解传入折叠的咖喱函数

问题描述

我在理解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, whenf是 curried 你有A => (B => B), 所以我想f.curried它正在工作,因为它与 相同(A => B => B),所以foldRight传入foldMap它所期望的(具有 type 的函数A => B),然后,接下来发生的是foldMap被调用并返回一个函数B => B,这就是你使用参数调用函数以获得最终结果的z时候。(f.curried)(z)B => BzB

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

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

标签: scalafoldmonoids

解决方案


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

  • 我宁愿说“所以我认为f.curried它正在工作,因为A => (B => B)它与”相同(A => B => B)这里f.curried是模棱两可的,你基本上是在谈论结果类型,而不是 with z
  • 我宁愿在这里加一个点而不是逗号:“foldMap正在期待一个函数 f: A => B 。在foldRight, ... ”以及几乎所有其他地方。更短的短语,更清晰的解释。
  • 什么可能是错误,(以及什么让您感到困惑?)是它(f.curried)(z)本身不起作用并且不在foldMap(as, endoMonoid[B]). 它是第foldMap(as, endoMonoid[B])(f.curried)一个被调用的,然后是(z). 第一个返回B => B并与第二个返回一起调用B

推荐阅读