How/why 这个函数在 OCaml 中合法吗?另外,我将如何检查这样的声明将来是否合法?

How/why is this function legal in OCaml? Also, how would I go about checking if statements like this one are legal in the future?

我不确定如何正确地执行此函数并确定其类型。我将其输入 OCaml 顶层,输出为 "hello world" 但我不知道为什么。有人可以解释一下他们是如何确定最终输出的吗?谢谢!

 let f y =  
    let z = (let x = 5 in y * x) + y in "hello" in (f 7) ^ " world"

嗯,整个事情都是基于 OCaml 构造 let a = b in c。如果匹配 letin 对,您可以看到表达式的结构。

let f y =
    let z = (let x = 5 in y * x) + y
    in "hello"
in (f 7) ^ " world"

本质上 f 是一个函数,它会做一些无用的计算然后 returns "hello".

更新

此代码有两个 let a = b in c 略有不同的用法。也许分开解释会更清楚

以下:

let y = expr1 in expr2

定义一个新名称y,其值由expr给出。然后可以在 expr2.

中使用名称 y

以下:

let f x = expr1 in expr2

定义函数f。定义 expr1 通常会使用参数 x 来计算一个有趣的值。然后在expr2.

中可以调用函数f

您的代码有两个第一个构造实例(定义值 zx)和第二个构造实例之一(定义函数 f)。

这个函数被特别混淆了,所以让我们仔细检查减少步骤:

let f y =  
    let z = (let x = 5 in y * x) + y in "hello" in (f 7) ^ " world"

==>

let f y = 
    let z = y * 5 + y in "hello" in (f 7) ^ " world"

==>

let f y = 
    let z = y * 5 + y in "hello" in (f 7) ^ " world"

此时很明显,z 未在函数 f 中使用,让我们将其删除:

let f y = "hello" in (f 7) ^ " world"

我们可以看到,实际上我们有 "function" f,总是 returns "hello":

let f y = "hello"

即定义在(f 7) ^ " world"范围内的表达式。 f 7 的计算结果为 "hello",我们有 "hello world"

let <name> = <expr-1> in <expr-2> 

有以下评价规则:

  1. 评价<expr-1>
  2. <expr-2> 中每个自由出现的 <name> 替换为 <expr-1>
  3. 评价<expr-2>