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

Posted

技术标签:

【中文标题】在 OCaml 中的 let 命令(即 let _ = ... in)中使用下划线通配符有啥副作用吗?【英文标题】:Any side effect of using underscore wildcard in let command (i.e., let _ = ... in) in OCaml?在 OCaml 中的 let 命令(即 let _ = ... in)中使用下划线通配符有什么副作用吗? 【发布时间】:2015-05-16 21:17:19 【问题描述】:

在使用 OCaml 时,我几乎总是在 let _ = exp 中使用下划线通配符,尤其是当 exp 的结果并不重要,但其中的计算很重要时。例如:

让 _ = print_endline "abc" in ... 让 _ = a := !a + 1 in ... 让 _ = do_some_thing ... 在

所以,我只是想知道广泛使用let _ = ... 是否有任何副作用?

【问题讨论】:

【参考方案1】:

副作用是将来在您的软件中跟踪令人讨厌的错误。 let _ = 的问题在于它会默默地忽略您打算全部的部分应用程序。假设您编写以下内容:

let f a b = ...
let _ = f 3 4

并且将来您向f添加一个参数:

let f a b c = ...

表达式let _ = f 3 4 仍将静默编译,您的程序不会调用该函数,让您想知道发生了什么。如果您需要忽略非单位结果,最好总是让() 并使用ignore

let () = ignore (f 3 4)
let () = print_endline "abc"

使用let _ = ... 应该被认为是不好的风格。

【讨论】:

副作用是将来在您的软件中跟踪令人讨厌的错误。 我完全同意。如果像使用let _ = … 序列那样明确地阻止编译器对类型做任何有用的事情,那么使用强类型语言有什么意义? 它不会被忽略:打印警告 5。 不符合 OCaml 的默认警告级别。【参考方案2】:

不,广泛使用let _ = 绝对没有任何后果。编译器不会为全局环境添加名称,因为您没有提供名称。

【讨论】:

【参考方案3】:

let 的目的是将值绑定到标识符。如果您只做副作用,最好将其包装在 begin .. end 块中。在你的情况下:

begin
    print_endline "abc";
    a := !a + 1;
    do_some_thing ();
end

【讨论】:

只有在前一个短语被;; 标记终止时才有效。

以上是关于在 OCaml 中的 let 命令(即 let _ = ... in)中使用下划线通配符有啥副作用吗?的主要内容,如果未能解决你的问题,请参考以下文章

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

用 let 重建 OCaml 模式

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

Lisp 的 let* 的 Ocaml 等价物?

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

如何可选地提供 OCaml (let*) 运算符以与新旧编译器一起使用?