在 OCAML 中使用 in 关键字

Using the in keyword in OCAML

我对关键字 in 在 OCAML 中的作用感到困惑。我什么时候需要使用它? 我接近理解的唯一例子是:

let quit_loop = ref false in
while not !quit_loop do
  print_string "Have you had enough yet? (y/n) ";
  let str = read_line () in
  if str.[0] = 'y' then
    quit_loop := true
done;;

let x = 10 in
let y = 20 in
x + y ;;

这里指的是什么?

最好的看待方式是 in 不是一个单独的关键字。相反,有一个看起来像 let v = expr1 in expr2 的表达式。这是 OCaml 中定义“本地”变量的方式。它的意思是你将使用 v 作为 expr2 中的命名值,它出现在 expr2 中时的值是 expr1 的值。

我怀疑这令人困惑的唯一原因是 OCaml 中有一个不同的结构来定义“全局”变量。在模块的顶层,您可以说 let v = expr。这定义了一个(通常)从模块导出的全局名称。

你举的例子都是第一种;也就是说,他们正在定义名为 quit_loopstrxy.

的局部变量

作为语法问题,in 主要用作标点符号;它允许语言的解析器判断 expr1 在哪里停止,expr2 在哪里开始。这在 ML 语言中尤其必要,因为将两个表达式并排放置具有特定(且非常常用)的含义。

更新

应要求,这里有一些例子 let ... in:

let compare_lengths a b =
    (* Here "let ... in" is used to name values used throughout
     * the computation (i.e., to make local variables).
     *)
    let alen = List.length a in
    let blen = List.length b in
    if alen < blen then -1
    else if alen > blen then 1
    else 0


let rec split list =
    (* Here "let ... in" is used to name
     * the parts of an intermediate result.
     *)
    match list with
    | [] -> ([], [])
    | (a, b) :: rest ->
        let (ra, rb) = split rest in
        (a :: ra, b :: rb)


let euclidean_distance (x1, y1) (x2, y2) =
    (* Here "let ... in" defines a nested helper function.
     *)
    let sqr f = f *. f in
    sqrt (sqr (x2 -. x1) +. sqr (y2 -. y1))