У меня проблемы с пониманием этого кода из книги FP в Scala.Вот код:
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
карри, у вас есть A => (B => B)
, поэтому яПредположим, что f.curried
работает, потому что это то же самое, что и (A => B => B)
, поэтому foldRight
передает foldMap
то, что ожидает (функция с типом A => B
), а затем происходит следующее: foldMap
вызывается и возвращает функцию B => B
, и именно тогда z
вступает в игру в (f.curried)(z)
, вы вызываете функцию B => B
с аргументом z
, чтобы получить окончательный B
.
Я прав?Для меня этот код немного сложен.
ПРИМЕЧАНИЕ: Вот scalafiddle , если вы хотите поиграть с ним.