Понимание функции карри передается в сложенном виде - PullRequest
5 голосов
/ 24 апреля 2019

У меня проблемы с пониманием этого кода из книги 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 , если вы хотите поиграть с ним.

1 Ответ

2 голосов
/ 24 апреля 2019

Ну, вы, кажется, в основном мне понятны.Тем не менее, я хотел бы уточнить некоторые моменты:

  • Я бы скорее сказал "поэтому я предполагаю, что 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.
...