На этом сайте написано, что точка с запятой семантически совпадает с let _ = ... in
, однако в следующем коде это не так. Этот код печатает None
и End
:
let m = None
let () =
let () = match m with
| None -> print_endline "None"
| Some file -> print_endline "Some"
in
print_endline "End";
Однако этот код печатает только None
.
let m = None
let () =
match m with
| None -> print_endline "None"
| Some file -> print_endline "Some"
;
print_endline "End";
Почему? В чем разница между точкой с запятой и let in
?
OCaml не чувствителен к пробелам. Ваш второй пример читается как
let m = None
let () =
match m with
| None -> print_endline "None"
| Some file -> print_endline "Some"; print_endline "End"
который печатает только End
в случае Some file
.
Другими словами, если вы переведете свой первый пример
let () =
let () = match m with
| None -> print_endline "None"
| Some file -> print_endline "Some"
in
print_endline "End"
чтобы использовать ;
, вам нужно заключить его в скобки:
let () =
(match m with
| None -> print_endline "None"
| Some file -> print_endline "Some"
);
print_endline "End"
чтобы разграничить выражение, заключенное в пару let ... in
.
Разъяснение того, что вы показали.
let _ = print_endline "hello" in
print_endline "world"
Не совсем эквивалентно:
print_endline "hello";
print_endline "world"
Шаблон _
, используемый в первом, будет соответствовать чему угодно. Рассмотрим немного другой надуманный пример:
# let _ = 42 in
print_endline "hello world";;
hello world
- : unit = ()
# 42; print_endline "hello world";;
Warning 10 [non-unit-statement]: this expression should have type unit.
hello world
- : unit = ()
На этот раз в последнем компилятор предупреждает нас, что 42
не оценивается как unit
. Это полезное предупреждение, позволяющее избежать потенциальных ошибок. Как и в коде octachron, это не проблема, если мы привязываемся к ()
, а не _
. Мы явно говорим, что значение не может быть ничем, а скорее должно оцениваться как unit
.
# let () = 42 in
print_endline "hello world";;
Error: This pattern matches values of type unit
but a pattern was expected which matches values of type int
Все-таки не совсем то. В этом случае мы получаем немедленную ошибку компилятора, а не предупреждение, но, по крайней мере, проблема не игнорируется полностью.
Помните, что
;
НЕ имеет того же значения, что и;;