在 OCaml 中分隔多个 let 声明后跟一个 let in 表达式
Separating multiple `let` declarations followed by a single `let in`expression in OCaml
这个问题详细说明了OCaml syntax trap: multiple lets using separators。
就编程命令式 OCaml 而言,如何在不将所有声明更改为表达式的情况下让多个 let
语句在单个 let ... in
之前运行?
例如,
let f x = x + 1
let g x = x + 2
let h x = x + 3
编译没有问题,但是
let f x = x + 1
let g x = x + 2
let h x = x + 3 in (Printf.printf "%d \n" (f (h (g 3))) ; ())
不起作用,因为前两个是声明而最后一个是表达式。同样的观察也适用于变量。纠正此错误的一种方法是将前两个 let
嵌套更改为表达式并嵌套 let...in
。然而,这看起来很乏味和笨拙:
let f x = x + 1 in
let g x = x + 2 in
let h x = x + 3 in (Printf.printf "%d \n" (f (h (g 3))) ; ())
或者,可以设想一个长的 OCaml 源代码文件,以多个 let
全局变量声明开始,中间有一个 let...in
表达式。在那种情况下,似乎需要 ;;
来终止顶部的声明,以便 let... in
起作用,但文档建议不要使用 ;;
。
还有其他写法(更优雅)吗?
不知道是不是更优雅,但是
let f x = x + 1
let g x = x + 2
let _ = let h x = x + 3 in Printf.printf "%d \n" (f (h (g 3)))
编译并运行。
如果我们坚持 top-level 项只能是定义1 的语法,那么理解 OCaml 语法会容易得多
let <patt> = <expr>
具有以下语义——计算表达式 <expr>
并将其应用于模式 <patt>
,如果匹配,则使用模式中绑定的变量丰富全局上下文 <patt>
.
因此,您的问题的常规解决方案是
let f x = x + 1
let g x = x + 2
let h x = x + 3
let () =
Printf.printf "%d \n" (f (h (g 3)));
()
由于历史原因,OCaml 允许在顶层使用 1
、"hello"
或 let x = 1 in x + x
等表达式,前提是您使用 ;;
将它们分开。这主要是由于与交互式 top-level 系统的兼容性,因此您可以将 OCaml 用作计算器。我建议不要在真正的 OCaml 程序中使用 ;;
,这些程序是为编译器使用而编写的。
1) 你称它们为declarations,虽然它们实际上是定义,但是对于我们的例子来说,这并不重要。
这个问题详细说明了OCaml syntax trap: multiple lets using separators。
就编程命令式 OCaml 而言,如何在不将所有声明更改为表达式的情况下让多个 let
语句在单个 let ... in
之前运行?
例如,
let f x = x + 1
let g x = x + 2
let h x = x + 3
编译没有问题,但是
let f x = x + 1
let g x = x + 2
let h x = x + 3 in (Printf.printf "%d \n" (f (h (g 3))) ; ())
不起作用,因为前两个是声明而最后一个是表达式。同样的观察也适用于变量。纠正此错误的一种方法是将前两个 let
嵌套更改为表达式并嵌套 let...in
。然而,这看起来很乏味和笨拙:
let f x = x + 1 in
let g x = x + 2 in
let h x = x + 3 in (Printf.printf "%d \n" (f (h (g 3))) ; ())
或者,可以设想一个长的 OCaml 源代码文件,以多个 let
全局变量声明开始,中间有一个 let...in
表达式。在那种情况下,似乎需要 ;;
来终止顶部的声明,以便 let... in
起作用,但文档建议不要使用 ;;
。
还有其他写法(更优雅)吗?
不知道是不是更优雅,但是
let f x = x + 1
let g x = x + 2
let _ = let h x = x + 3 in Printf.printf "%d \n" (f (h (g 3)))
编译并运行。
如果我们坚持 top-level 项只能是定义1 的语法,那么理解 OCaml 语法会容易得多
let <patt> = <expr>
具有以下语义——计算表达式 <expr>
并将其应用于模式 <patt>
,如果匹配,则使用模式中绑定的变量丰富全局上下文 <patt>
.
因此,您的问题的常规解决方案是
let f x = x + 1
let g x = x + 2
let h x = x + 3
let () =
Printf.printf "%d \n" (f (h (g 3)));
()
由于历史原因,OCaml 允许在顶层使用 1
、"hello"
或 let x = 1 in x + x
等表达式,前提是您使用 ;;
将它们分开。这主要是由于与交互式 top-level 系统的兼容性,因此您可以将 OCaml 用作计算器。我建议不要在真正的 OCaml 程序中使用 ;;
,这些程序是为编译器使用而编写的。
1) 你称它们为declarations,虽然它们实际上是定义,但是对于我们的例子来说,这并不重要。