OCAML代码中的需求和目的`()和`



我试图从这里理解OCAML并运行遵循代码:

let rec fib n =  
  if n < 2 then 1 else fib (n-1) + fib (n-2);;
let main () =
  let arg = int_of_string Sys.argv.(1) in
  print_int (fib arg);
  print_newline ();
  exit 0;;
main ();;

但是,我不明白为什么需要()in,以及为什么遵循代码(更清洁(不起作用:

let rec fib n =
  if n < 2 then 1 else fib (n-1) + fib (n-2);;
let main =
  let arg = int_of_string Sys.argv.(1);
  print_int (fib arg);
  print_newline;
  exit 0;;  (* Line 7. Error is coming from here.*)
main;;

上面的代码给出以下错误:

File "fib_simpler.ml", line 7, characters 8-10:
Error: Syntax error

我注意到,删除()仅发出警告,而删除in给出了错误和程序执行停止。

在print_newline之后保持in()删除所有警告和错误。因此,main关键字实际上并不需要()

上面的评论显示:

let rec fib n =  (*(n) also works here*)
  if n < 2 then 1 else fib (n-1) + fib (n-2);;
let main () =  (*removing () here does not matter*)
  let arg = int_of_string Sys.argv.(1) in (* in keyword is essential here*)
  print_int (fib arg);
  print_newline ();  (*removing () causes warning *)
  exit 0;;
main ();;      (*removing () here does not matter*)

任何解释都将不胜感激。

ocaml是一种基于表达的语言。它没有语句,因此;不是语句终结者,而是序列运算符(类似于C的逗号运算符(。<expr1>; <expr2>大约只是let () = <expr1> in <expr2>的短手。它评估expr1,丢弃其值,然后评估expr2并返回该值。

let <pattern> = <expr1> in <expr2>是一种表达式,根据<pattern>绑定expr1的结果,在expr2的背景下,它可能只是简单的标识符或更复杂的记录模式。<pattern>创建的绑定将不存在于expr2之外。

使用 (),在绑定中称为"单位"定义一个函数。如果您省略了参数,则不会定义一个函数,而只是一个值。区别在于,一个值立即评估,而仅一次,而通过将参数应用于该函数时,将评估函数。必须将()作为参数的函数作为执行()的参数,否则您只是将函数本身传递到周围。而且,如果您像上面一样丢弃它,那几乎总是一个错误。因此警告。

简而言之:

  • let arg = int_of_string Sys.argv.(1); ...没有in分隔两个表达式是语法错误。编译器直到到达当前表达式的末尾并发现在那里找不到in

  • let main () = ...定义一个函数

  • let main = ...定义值

  • print_newline (); ...将参数()应用于print_newline,从而执行它,然后丢弃返回值

  • print_newline; ...实际上没有做任何事情

最后,如果您只想执行main一次,则可以减少

let main () = ...;;
main;;

to

let () = ...;;

除非您要多次使用命名功能。

最新更新