当differant记录类型具有共同标签时,访问ocaml记录的成员

Jos*_*cid 2 ocaml types record

我已经定义了两种记录类型如下:

(* in module A*)
type reg = {name: string; mutable value: Big_int.big_int}
type exp = Reg of reg | Other
Run Code Online (Sandbox Code Playgroud)
(* in module B*)
type abstr = Top | Bot | Elt of int
type register = {name: string; mutable value: abstr}
Run Code Online (Sandbox Code Playgroud)

在模块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
Run Code Online (Sandbox Code Playgroud)

但是我得到以下错误:表达式具有类型A.reg但是期望类型为register.模块A中的定义似乎被模块B中的定义隐藏.如果是,为什么会这样?谁能解释一下?

Jef*_*eld 5

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

value.Module.field
Run Code Online (Sandbox Code Playgroud)

在你的情况下,它将是:

r.A.name
Run Code Online (Sandbox Code Playgroud)

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

回答"为什么会这样":获得(精彩和奇妙)类型推断的传统是编译器不能从事物的类型中推断出重载名称的含义.推论是另一种方式(实质上).因此,您无法区分name基于类型命名的两个字段,您需要明确指出您的意思.类似的限制表现在整数和浮点算术运算符之间的区别.


Ash*_*wal 5

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