Я отвечу на свой вопрос, чтобы, возможно, предоставить полезную перспективу тем, кто посещает этот вопрос.
Мы хотим реализовать следующую программу с двумя привязками let:
let times a b = a * b
square x = times x x
in square 5
Для начала давайте упростим это до сути того, что мы хотим:
square 5
Достаточно просто. Однако square
в этом случае не определено! Ну, мы можем связать это, используя механизм, который обеспечивает нам наш язык - лямбда. Это дает нам (\ square -> square 5) (\x -> times x x)
. Теперь square
определен, но его двоюродный брат times
не ... Ну, нам нужна еще одна лямбда! Наша финальная программа должна выглядеть так:
(\times -> (\square -> square 5) (\x -> times x x)) (\a b -> a * b)
Обратите внимание, что (\times -> ...)
полностью охватывает наш последний шаг, так что times
будет находиться в области видимости, поскольку он связан. Это согласуется с ответом @rampion и сокращается следующим образом:
(\times -> (\square -> square 5) (\x -> times x x)) (\a b -> a * b) =>
(\square -> square 5) (\x -> (\a b -> a * b) x x) =>
(\square -> square 5) (\x -> (\b -> x * b) x) =>
(\square -> square 5) (\x -> x * x) =>
(\x -> x * x) 5 =>
5 * 5 =>
25
Если бы функция square
не зависела от times
, мы могли бы легко написать (\times square -> ....
. Зависимость означает, что мы должны вкладывать эти две среды, одна из которых содержит times
, а другая внутри той, которая может использовать ее определение.
Спасибо за вашу помощь! Я поражен простотой и мощью лямбда-исчисления.