这个语法在OCaml中来自哪里?

时间:2015-10-14 18:18:08

标签: ocaml

this video中,显示了使用oUnit的单元测试。测试由这样的代码片段定义:

let test_fixture = "SimpleMath" >:::
[
    "add" >:: (fun () -> 
      assert_equal 4 (SimpleMath.add 2 2);
      assert_equal 0 (SimpleMath.add 0 0)
      );

    "subtract" >:: (fun () -> 
      assert_equal 4 (SimpleMath.subtract 9 3);
      assert_equal 3 (SimpleMath.subtract 5 2)
      )
 ]

let _ = run_test_tt test_fixture

为什么使用单个分号?我在课堂上教过你总是用双分号作为指示。为什么我们将返回值分配给模式? run_test_ttrun_test_tt_main之间有什么区别吗?我无法在文档中找到它。

来自另一个例子

let test1 test_ctxt = assert_equal "x" (Foo.unity "x");;

为什么我们将类型(!)设置为函数参数?

1 个答案:

答案 0 :(得分:4)

单个分号(实质上)是一个运算符,它通过忽略第一个表达式的值并返回第二个表达式的值来组合两个表达式。

换句话说,对于命令式代码,它在许多其他语言中就像一个分号。

双分号是一个特殊的符号,告诉你想要它评估你到目前为止输入的内容。在我的(谦虚)意见中,你应该只在将代码输入顶级时使用它。它与;运算符没有实际关系。

似乎存在一种相当普遍的误解,即;;是OCaml语法的某种重要部分。我不这么认为;它只是一种与顶层沟通的方式(类似于#use#show_module)。

<强>更新

你问你是否可以这样写:

let x = 4; print_int x

答案是否定的,你不能写这个。但这是因为x没有先前的价值。此代码解析如下:

let x = (4; print_int x)

如您所见,这会尝试打印之前的x值。 <{1}}在评估x时尚未绑定。

在OCaml中定义局部变量的方法是print_int。所以你可以输入let var = expr1 in expr2。 (就个人而言,我不明白为什么分号会更好。)

如果删除let x = 4 in print_int x,则表示您的代码无法解析。如果您在模块的顶层混合使用命令式代码,就会发生这种情况。我的解决方案根本就是不这样做。所以不要在模块中写这样的东西:

;;

我写了以下内容:

Print.printf "Welcome to module\n"

如果您的示例出现在模块的顶层,我会写这个:

let () = Printf.printf "Welcome to module\n"

(注意,根本没有分号!)

另请注意,原始帖子中的代码遵循此约定,但他们写的是let x = 4 let () = print_int x 而不是let _ = ...