Наверное, вы имели ввиду
add 2
, тогда мы применим только первый аргумент функции. Когда мы так делаем, на выходе получаем функцию с одним аргументом, потому что первый аргумент уже равен 2. Можете считать, что он просто сохранен внутри этой функции, чтобы быть использованным, когда функция будет полностью применена.
Что вообще происходит в теле возвращаемой функции?
Так немного некорректно рассуждать, потому что компилятор может по-разному оптимизировать внутренность функции.
Но если вам будет проще понять, можно представить, что у нас не Хаскель, а обычный императивный язык. Тогда частичное применение можно эмулировать с помощью замыкания:
func main() {
fmt.Println(sum(1, 2))
carried := carry(sum, 1)
fmt.Println(carried(2))
}
func sum(a, b int) int {
return a + b
}
func carry(fn func(int, int) int, a int) func(int) int {
return func(b int) int {
return fn(a, b)
}
}
https://go.dev/play/p/dp6W3U5bSGq
То есть, когда вы частично применяете функцию, можете считать, что примененный аргумент сохранился в переменной внутри "обертки", которая возникает вокруг этой функции. В Хаскеле просто это делается очень удобно синтаксически, в отличие от других языков.