我对OCaml中的and
关键字感到困惑。浏览this code,我看到了
type env = {
(* fields for a local environment described here *)
}
and genv {
(* fields for a global environment here *)
}
然后later,
let rec debug stack env (r, ty) = (* a function definition *)
and debugl stack env x = (* another function definition *)
这里发生了什么? and
关键字是否只复制了上一个type
,let
或let rec
声明?有and rec
陈述这样的事吗?为什么我要使用and
而不是仅仅键入let
或type
,这使得我的代码对于重构不那么脆弱?还有什么我应该知道的吗?
答案 0 :(得分:16)
and
关键字用于避免多个let
(第一个例子,我从不使用它,但为什么不使用它)或者用于相互递归的类型,函数,模块定义... < / p>
正如您在第二个例子中所看到的那样:
let rec debug stack env (r, ty) =
...
| Tunresolved tyl -> o "intersect("; debugl stack env tyl; o ")"
...
and debugl stack env x =
...
| [x] -> debug stack env x
...
debug
调用debugl
,反之亦然。所以and
允许这样做。
[编辑]我不打算给出一个正确的例子,所以这里有一个你经常看到的例子:
let rec is_even x =
if x = 0 then true else is_odd (x - 1)
and is_odd x =
if x = 0 then false else is_even (x - 1)
(您可以找到此示例here)
对于相互递归的类型,找到配置比较困难,但在this wikipedia page之后,我们会定义trees
和forests
,如下所示
type 'a tree = Empty | Node of 'a * 'a forest
and 'a forest = Nil | Cons of 'a tree * 'a forest
例如,一个由空树组成的森林,标有“&#39; a&#39;和一个带有标签的双节点树&#39; b&#39;和&#39; c&#39;然后表示为:
let f1 = Cons (Empty, (* Empty tree *)
Cons (Node ('a', (* Singleton tree *)
Nil), (* End of the first tree *)
Cons (Node ('b', (* Tree composed by 'b'... *)
Cons (Node ('c', (* and 'c' *)
Nil),
Nil)
),
Nil (* End ot the second tree *)
)
)
);;
size函数(计算林中节点数)将是:
let rec size_tree = function
| Empty -> 0
| Node (_, f) -> 1 + size_forest f
and size_forest = function
| Nil -> 0
| Cons (t, f) -> size_tree t + size_forest f
我们得到了
# size_forest f1;;
- : int = 3