scala - 了解传入折叠的咖喱函数
问题描述
我在理解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 => B
z
B
我对吗?对我来说,推理这段代码有点复杂。
注意:如果你想玩它,这里是一个scalafiddle 。
解决方案
好吧,你对我来说似乎很全面。不过,我要澄清几点:
- 我宁愿说“所以我认为
f.curried
它正在工作,因为A => (B => B)
它与”相同(A => B => B)
(这里f.curried
是模棱两可的,你基本上是在谈论结果类型,而不是 withz
) - 我宁愿在这里加一个点而不是逗号:“
foldMap
正在期待一个函数 f: A => B 。在foldRight, ... ”以及几乎所有其他地方。更短的短语,更清晰的解释。 - 什么可能是错误,(以及什么让您感到困惑?)是它
(f.curried)(z)
本身不起作用并且不在foldMap(as, endoMonoid[B])
. 它是第foldMap(as, endoMonoid[B])(f.curried)
一个被调用的,然后是(z)
. 第一个返回B => B
并与第二个返回一起调用B
。
推荐阅读
- python - 如何从 json 文件中删除某些注释?(/*)
- r - 在上传到 shinyapps.io 的 Shiny 应用中打开 .rda 文件
- bash - 如何在 Linux 中杀死前 3 个消耗进程?
- ios - 错误 E_IAP_NOT_AVAILABLE 和 iOS 14:RNIap.getProducts()/RNIap.getSubscriptions Unknown Error throw
- amazon-web-services - 如何从 Amazon S3 文件重定向到我的网站?
- android - 在 Whatsapp 上分享图片:Android
- java - 我是否受到此 Google Drive API 更改的影响?
- javascript - C# SHA512 shaM ComputeHash 应该如何实现 Angular10 或 Javascript
- java - 使用 SAP Cloud Security 在 Java 中创建 JWT 令牌
- javascript - MongoDb 过滤器获取两个日期之间的对象