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

Posted

技术标签:

【中文标题】在 OCaml 中分隔多个“let”声明,后跟一个“let in”表达式【英文标题】:Separating multiple `let` declarations followed by a single `let in`expression in OCaml 【发布时间】:2019-10-14 05:25:27 【问题描述】:

这个问题详细阐述了OCaml syntax trap: multiple lets using separators。

就编程命令式 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】:

如果我们坚持***项目可能只是一个定义1的语法,那么理解OCaml语法会容易得多,其形式为

let <patt> = <expr>

具有以下语义——计算表达式&lt;expr&gt;并将其应用于模式&lt;patt&gt;,如果匹配,则使用模式&lt;patt&gt;中绑定的变量丰富全局上下文。

因此,您的问题的常规解决方案是

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) 你称它们为声明,虽然它们实际上是定义,但是对于我们的例子来说,这并不重要。

【讨论】:

【参考方案2】:

不知道是不是更优雅,但是

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

编译并运行。

【讨论】:

以上是关于在 OCaml 中分隔多个“let”声明,后跟一个“let in”表达式的主要内容,如果未能解决你的问题,请参考以下文章

iOS:如何在一个数组中的多个字典中分隔键值?

如何在cfmail中分隔多个电子邮件地址

“let () =”在 Ocaml 中是啥意思?

OCaml - 如何在匹配表达式中放置一个 let 绑定?

在 OCaml 中的 let 命令(即 let _ = ... in)中使用下划线通配符有啥副作用吗?

Ocaml中“type ...and”和“let ...and”之间的范围不一致