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