OCaml类型具有不同的特异性水平

Mat*_*lly 9 ocaml interface

我试图模拟OCaml中的接口,并使用"类型"构造.我有两种类型:

type fooSansBar = {a: string; b: int};;
type fooConBar = {a:string; b:int; bar:char};;
Run Code Online (Sandbox Code Playgroud)

...并且想要定义一个特定的fooSansBar:

let fsb = {a="a"; b=3};;
Run Code Online (Sandbox Code Playgroud)

...但是我被告知条形区域没有定义.由此看来,与我在匹配fooSansBar签名时传递的值相反,系统认为我正在尝试创建一个fooConBar.如果存在上面定义的两种类型,是否可以创建fooSansBar?

另外(因为我是OCaml的新手)有更好的方法来模拟界面吗?

Nor*_*sey 9

在OCaml中,记录类型中的字段名称必须是唯一的,因此您定义的两种类型不能同时共存.Caml是我所知道的唯一一种语言.

因为第二个定义隐藏了第一个定义,当编译器看到a和b字段时,它期望它们属于该fooConBar类型,因此会抱怨缺少的bar字段.

如果您正在尝试模拟接口,那么在Caml中执行此操作的正确方法是定义一个module type.

module type FOO_CON_BAR = sig
  val a : string
  val b : int
  val bar : char
end
Run Code Online (Sandbox Code Playgroud)

一个例子:

module Example = struct
  let a = "hello"
  let b = 99
  let c = '\n'
end
Run Code Online (Sandbox Code Playgroud)

使用模块和模块类型,您也可以获得子类型; 没有必要求助于物体.

PS我的Caml生锈了; 语法可能已关闭.


sma*_*uck 3

第二种类型重新定义了 a 和 b,有效地隐藏了第一种类型,这就是它无法再被构造的原因。您可以在不同的模块中定义这些类型,但这与对 a 和 b 使用不同的名称相同。

仅当您不尝试从另一个接口“派生”而只是实现它时,才能使用这些构造。

如果您希望在 Ocaml 中使用这些面向对象的概念,您可以查看对象系统,或者根据您的问题查看模块系统。或者,您可以尝试以实用的方式解决您的问题。您想解决什么问题?