[英]OCaml delimiters and scopes
我正在学习OCaml,尽管我在命令式编程语言(C,C ++,Java)方面有多年的经验,但OCaml语法中的声明或表达式之间的分隔符却出现了一些问题。
基本上我明白我必须用;
连接表达式,该序列返回的值将是最后使用的表达式之一,例如,如果我有
exp1; exp2; exp3
它将被视为返回exp3
值的表达式。 从这个开始我可以使用
let t = something in exp1; exp2; exp3
而且应该没问题吧?
我什么时候应该使用double semicol ;;
? 这到底是什么意思?
我还必须使用其他分隔符来避免语法错误吗?
我举一个例子:
let rec satisfy dtmc state pformula =
match (state, pformula) with
(state, `Next sformula) ->
let s = satisfy_each dtmc sformula
and adder a state =
let p = 0.;
for i = 0 to dtmc.matrix.rows do
p <- p +. get dtmc.matrix i state.index
done;
a +. p
in
List.fold_left adder 0. s
| _ -> []
它给了我语法错误上|
但我不明白为什么..我想念什么? 这是一个经常发生的问题,我不得不尝试许多不同的解决方案,直到它突然起作用:/
附带的问题:用let
声明let .. in
将定义一个var绑定,该绑定let .. in
定义后一直存在?
我基本上要问的是:什么是分隔符,什么时候必须使用。 另外,在使用解释器ocaml
而不是编译器ocamlc?
,我应该考虑ocamlc?
提前致谢!
let p = 0.;
这是错误。 的;
必须是in
。 不能使用let
不in
只定义全局的功能,你不能使用它在表达式中。
附带的问题:用let声明let .. in将定义一个var绑定,该绑定在定义后一直存在?
您只能使用一个或另一个(允许在交互式解释器中混合使用表达式和定义)。 当定义一个全局函数或价值,你需要let
没有in
。 在表达式中,你需要let
同in
。
;;
用于终止输入并在ocaml
REPL中开始解释,使用ocamlc
或ocamlopt
编译时没有特殊含义。
您不能使用<-
运算符将其赋给任意值,必须将ref
类型用于可变变量:
let p = ref 0. in
for i = 0 to dtmc.matrix.rows do
p := !p +. get dtmc.matrix i state.index
done;
a +. !p
;;
定界符终止顶级实体。 在ocaml
顶层(解释程序)中,它向解释程序发出信号,指示特定输入已完成并且应进行评估。
在要用ocamlc
或ocamlopt
编译的程序中,您不需要那么频繁,因为连续的顶层let
(无in
), module
, type
, exception
和类似的语句会自动表示新“短语”的开始。 如果在模块中包括仅用于评估其副作用(例如生成某些输出或注册模块)的顶级表达式,则需要使用;;
在告诉编译器停止编译之前的短语并开始编译新事物之前。 否则,如果上一件事是let
,它将假定新表达式是let的一部分。 例如:
let msg = "Hello, world";; (* we need ;; here *)
print_endline msg;; (* ;; is optional here, unless we have another expression *)
当您需要和不需要时;;
有点微妙,所以我通常用它终止我所有的模块级实体,所以我不必担心何时需要它。
;
用于在单个表达式中分隔顺序的“语句”。 因此foo; bar
foo; bar
是由foo
和bar
组成的单个顺序表达式,而foo;; bar
foo;; bar
仅在模块的顶层有效,并表示两个表达式。
在let
not in
:该构造仅在模块定义中有效,因此绑定的变量将在模块末尾绑定。 通常,这只是文件的结尾。 但是,如果您有嵌套模块,则其范围可能会受到更多限制。 除非它在本地模块定义中,否则它不能在其他表达式或定义(例如函数定义)中使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.