2

我定义了两种记录类型,如下所示:

(* in module A*)
type reg = {name: string; mutable value: Big_int.big_int}
type exp = Reg of reg | Other

(* in module B*)
type abstr = Top | Bot | Elt of int
type register = {name: string; mutable value: abstr}

在模块 B 中,我有一个列表,我称之为l,exp并且我正在对其进行模式匹配。所以我有这样的事情:

 List.fold_left (fun l elt ->
     let str =
        match elt with
           | A.Reg r -> r.name
           | _ -> failwith "exception" in
      l@[{name = str; value = Bot}]) [] l

但是我收到以下错误:表达式的类型为 A.reg 但预期为 register 类型。看来模块A中的定义被模块B中的定义隐藏了。如果是,为什么会这样?有人可以解释吗?

4

2 回答 2

5

记录不能在 OCaml 中共享字段名称。exp记录类型中的字段全名为A.nameA.value。与其他命名元素一样,在模块 A 中,您可以省略A.前缀。但是,在不同的模块中,您必须使用完全限定名称(除非您已打开A)。换句话说,写信r.A.name来解决你的错误。

于 2012-08-06T15:07:34.180 回答
5

要使用模块中的记录字段名称,您需要键入:

value.Module.field

在您的情况下,它将是:

r.A.name

我认为 Deokhwan Kim 也是对的,你想要A.Reg而不是A.reg.

回答“为什么会这样”:获得(奇妙而奇妙的)类型推断的权衡是编译器无法从事物的类型中推断出重载名称的含义。推论是相反的(本质上)。因此,您无法区分name基于类型命名的两个字段,您需要明确说明您的意思。整数和浮点算术运算符之间的区别也有类似的限制。

于 2012-08-06T15:02:13.247 回答