Позвольте мне представить этот вопрос в качестве примера. Это было взято из лекции 2.3 курса Мартина Одерского по функциональному программированию.
У меня есть функция для итеративного поиска фиксированных точек, например
object fixed_points {
println("Welcome to Fixed Points")
val tolerance = 0.0001
def isCloseEnough(x: Double, y: Double) =
abs((x-y)/x) < tolerance
def fixedPoint(f: Double => Double)(firstGuess: Double) = {
def iterate(guess: Double): Double = {
println(guess)
val next = f(guess)
if (isCloseEnough(guess, next)) next
else iterate(next)
}
iterate(firstGuess)
}
Я могу адаптировать эту функцию для поиска квадратных корней, например так
def sqrt(x: Double) =
fixedPoint(y => x/y)(1.0)
Однако это не сходится для определенных аргументов (например, 4). Поэтому я применяю к нему среднее демпфирование, по сути, преобразовывая его в Ньютон-Рафсон, вот так
def sqrt(x: Double) =
fixedPoint(y => (x/y+y)/2)(1.0)
который сходится.
Теперь среднее демпфирование является достаточно общим, чтобы гарантировать свою собственную функцию, поэтому я реорганизую свой код следующим образом.
def averageDamp(f: Double => Double)(x: Double) = (x+f(x))/2
и
def sqrtDamp(x: Double) =
fixedPoint(averageDamp(y=>x/y))(1.0) (*)
Вау! Что только что произошло?? Я использую averageDamp
только с одним параметром (когда он был определен с двумя), и компилятор не жалуется!
Теперь я понимаю, что могу использовать частичное приложение так
def a = averageDamp(x=>2*x)_
a(3) // returns 4.5
Там нет проблем. Но когда я пытаюсь использовать averageDamp
с меньшим количеством параметров, чем необходимо (как это было сделано в sqrtDamp
), вот так
def a = averageDamp(x=>2*x) (**)
Я получаю сообщение об ошибке missing arguments for method averageDamp
.
Вопросы:
- Чем то, что я сделал в (**), отличается от (*), на что компилятор жалуется в первом, но не во втором?
- Таким образом, похоже, что при определенных обстоятельствах допускается использование меньшего количества необходимых параметров. Что это за обстоятельства и как называется этот механизм? (Я понимаю, что это подпадает под тему «каррирования», но я как бы ищу конкретное название этого подмножества каррирования)
fixedPoint
принимает функцию, поэтому она готова расширить ваш аргумент. Другое использование не имеет ожидаемого типа, поэтому не будет. Это часто задаваемые вопросы. - person som-snytt   schedule 25.11.2015