Ocaml 中的嵌套 "Let" 表达式
Nested "Let" expressions in Ocaml
全部:
如何在 "Curry" 语法中编写以下内容:
let y = 2 in
let f x = x + y in
let f x = let y = 3 in f y in
f 5
我最初尝试过这样的事情:
(y -> (f -> ((f x -> f 5) (y -> f y) 3)) x + y) 2
然而,这似乎无法正确评估。
更好的是使用 Lambda 表达式来查看绑定。
谢谢!
let v = e1 in e2
将 lambda 演算转换为 (\v.e2)(e1)
(我使用反斜杠表示 lambda)。所以,你的例子是
(\y1.(\f1.(\f2.f2 5)(\x2.(\y2.f1(y2))(3)))(\x1.x1+y1))(2)
我使用 alpha 转换来区分具有相同名称的变量。观察中间的f
变成了f1
,也就是你例子第三行f y
中的f
使用了定义在第二行,而不是即将在第三行中定义的行。换句话说,您的定义不是递归的;您使用的是 let
,而不是 let rec
。
题外话:将 let rec
转换为 lambda 演算需要一个定点组合器 Y
(或类似技术)。 Y
的特点是 Y(f)
减少为 f(Y(f))
的 属性。然后,let rec v = e1 in e2
大致翻译为 (\v.e2)(Y(\v.e1))
.
全部:
如何在 "Curry" 语法中编写以下内容:
let y = 2 in
let f x = x + y in
let f x = let y = 3 in f y in
f 5
我最初尝试过这样的事情:
(y -> (f -> ((f x -> f 5) (y -> f y) 3)) x + y) 2
然而,这似乎无法正确评估。
更好的是使用 Lambda 表达式来查看绑定。
谢谢!
let v = e1 in e2
将 lambda 演算转换为 (\v.e2)(e1)
(我使用反斜杠表示 lambda)。所以,你的例子是
(\y1.(\f1.(\f2.f2 5)(\x2.(\y2.f1(y2))(3)))(\x1.x1+y1))(2)
我使用 alpha 转换来区分具有相同名称的变量。观察中间的f
变成了f1
,也就是你例子第三行f y
中的f
使用了定义在第二行,而不是即将在第三行中定义的行。换句话说,您的定义不是递归的;您使用的是 let
,而不是 let rec
。
题外话:将 let rec
转换为 lambda 演算需要一个定点组合器 Y
(或类似技术)。 Y
的特点是 Y(f)
减少为 f(Y(f))
的 属性。然后,let rec v = e1 in e2
大致翻译为 (\v.e2)(Y(\v.e1))
.