Я больше знаком с ocaml, но для меня все выглядит одинаково.
val y=2;
fun f(x) = x*y;
Первые две строки связывают переменные y
и f
. y
в целое число 2
и f
в функцию, которая принимает целое число x
и умножает его на то, что связано с y
, 2
. Таким образом, вы можете подумать, что функция f
берет некоторое целое число и умножает его на 2
. (f(x) = x*2
)
fun g(h) = let val y=5
in
3+h(y)
end;
Следующая строка определяет функцию g
, которая принимает значение h
(которое оказывается функцией, которая принимает целое число и возвращает целое число) и выполняет следующее:
- Связывает целое число
5
с временной переменной y
.
- Вы можете думать о синтаксисе
let
/ in
/ end
как о способе объявления временной переменной, которая может использоваться в выражении, следующем за in
. end
просто заканчивает выражение. (это в отличие от ocaml, где end
опущено)
- Возвращает сумму
3
плюс функция h
, применяющая аргумент y
или 5
.
На высоком уровне функция g
принимает некоторую функцию, применяет 5
к этой функции и добавляет 3
к результату. (g(h) = 3+h(5)
)
На данный момент в среде связаны три переменные: y = 2
, f = function
и g = function
.
let val y=3
in
g(f)
end;
Теперь 3
привязан к временной переменной y
и вызывает функцию g
с функцией f
в качестве аргумента. Вы должны помнить, что когда функция определена, она сохраняет свою среду вместе с ней, поэтому временная привязка y
здесь не влияет на функции g
и f
. Их поведение не меняется.
g
(g(h) = 3+h(5)
), вызывается с аргументом f
(f(x) = x*2
). Выполнение замен для параметра h
, g
становится 3+((5)*2)
, что оценивается как 13
.
Надеюсь, вам это ясно.