Упражнение 6.8, Кьюзано и Бьярнасон, Функциональное программирование в Scala, с. 87 спрашивает, как можно реализовать flatMap() для следующего трейта:
trait RNG {
def nextInt: (Int, RNG)
}
type Rand[+A] = RNG => (A, RNG)
Ключ ответа дает следующее решение:
def flatMap[A,B](f: Rand[A])(g: A => Rand[B]): Rand[B] =
rng => {
val (a, r1) = f(rng)
g(a)(r1) // We pass the new state along
}
Stackoverflow дает много ответов на вопросы о flatMap()/monad, но ни один из них не ответил мне на мои вопросы относительно предпоследней строки кода.
Я не понимаю синтаксис строки
g(a)(r1)
(1) Я не понимаю, как вычисляется g(a)(r1). Какую синтаксическую функцию выполняет (r1)? Строка не иллюстрирует каррирование, я не верю, так как g принимает только один аргумент: A. (2) Если g(a) уже вернет тип Rand[B], то почему строка не заканчивается здесь? (3) какова связь между Rand[B], возвращаемым функцией g(a), и вторым набором скобок: (r1)? (4) если возвращаемый тип этой реализации flatMap() — Rand[B], что равно RNG => (A, RNG), как генерируются закрывающие круглые скобки справа от стрелки? Если бы мне пришлось угадывать, я бы сказал, что они генерируются оценкой (r1), но я не очень понимаю этот код, учитывая мои вопросы с 1 по 3.