Types 当不同的记录类型具有公共标签时访问ocaml记录的成员

Types 当不同的记录类型具有公共标签时访问ocaml记录的成员,types,ocaml,record,Types,Ocaml,Record,我定义了两种记录类型,如下所示: (* in module A*) type reg = {name: string; mutable value: Big_int.big_int} type exp = Reg of reg | Other 在模块B中,我有一个列表,我称之为l,属于exp,我正在对其进行模式匹配。所以我有这样的想法: List.fold_left (fun l elt -> let str = match elt with

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

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

在模块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中的定义所隐藏。如果是,为什么是这样?有人能解释一下吗?

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

value.Module.field
在您的情况下,它将是:

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


在回答“为什么是这样”时:获得(奇妙而奇妙的)类型推断的折衷办法是编译器不能从类型中推断重载名称的含义。推论(本质上)是相反的。因此,您无法根据类型区分名为
name
的两个字段,您需要明确说明您指的是哪一个字段。整数和浮点算术运算符之间的区别也存在类似的限制。

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

你能试着用
A.Reg
代替
A.Reg
?这就是我在代码中实际使用的,所以类型推断就是原因。。ThanksI已经打开了一个,但仍然必须使用完全限定的名称
r.A.name