在 OCaml 中分隔多个"let"声明,后跟一个"let in"表达式



这个问题详细阐述了OCaml语法陷阱:使用分隔符的多个let。

在编程命令式 OCaml 方面,如何在不将所有声明更改为表达式的情况下,在单个let ... in之前运行多个let语句?

例如

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))) ; ())

不起作用,因为前两个是声明,而最后一个是表达式。同样的观察结果也适用于变量。纠正此错误的一种方法是将前两个lets嵌套到表达式中并嵌套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正常工作,但文档建议不要使用该;;

有没有另一种写法(更优雅)?

如果我们坚持使用顶级项目只能是定义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之类的表达式,前提是您使用;;将它们分开。这主要是由于与交互式顶级系统的兼容性,因此您可以将 OCaml 用作计算器。我建议不要在真正的OCaml程序中使用;;,这些程序是为编译器使用而编写的。


1)你称它们为声明,尽管它们实际上是定义,但是对于我们的情况来说,这并不重要。

我不知道它是否更优雅,但是

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)))

编译并运行。

相关内容

  • 没有找到相关文章

最新更新