Object OCaml中的多态对象更新

Object OCaml中的多态对象更新,object,polymorphism,ocaml,Object,Polymorphism,Ocaml,我想实现一个系统,其中对象在其字段内容上是多态的,并且内容可以更改。也就是说,对象提供了一种通用方法,可以将字段f与类型a\u t的值a和类型b\u t的值b交换给每个字段f 第一次尝试是这样的: class ['a] not_working (a : 'a) = object val _a = a method field_a = _a method modify_a new_a = {< _a = new_a >} end i、 e.修改产生相同类型的对象 我的

我想实现一个系统,其中对象在其字段内容上是多态的,并且内容可以更改。也就是说,对象提供了一种通用方法,可以将字段f与类型a\u t的值a和类型b\u t的值b交换给每个字段f

第一次尝试是这样的:

class ['a] not_working (a : 'a) = object 
  val _a = a
  method field_a = _a
  method modify_a new_a = {< _a = new_a >}
end 
i、 e.修改产生相同类型的对象

我的解决方法如下:

class ['fields_t] the_class (fields : 'fields_t) = object

  method field_a = fields#field_a

  method field_b = fields#field_b

end

let modify_field_a instance new_a = new the_class (object method field_a = new_a ; method field_b = instance#field_b end)

let modify_field_b instance new_b = new the_class (object method field_a = instance#field_a ; method field_b = new_b end)

let instance = new the_class (object method field_a = 1 ; method field_b = "foo" end)

let mod_instance = modify_field_a instance "1"
我为_类中的每个字段生成一个修改函数,该修改函数更新该字段并复制所有其他字段。这太吵了


有没有一种方法可以以类似的方式使用对象复制操作符或类似的构造来简化样板文件?

我不认为您可以对对象执行您想要的操作,因为我认为这将涉及一种非常规递归类型:

type 'a foo = < modify: 'b. 'b -> 'b foo >
如果尝试定义该类型,请注意错误消息:

Characters 4-42:
  type 'a foo = < modify: 'b. 'b -> 'b foo >;;
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: In the definition of foo, type 'b foo should be 'a foo
使用记录或一流模块可能会更幸运:

# type ('a, 'b) foo = { a: 'a; b: 'b };;
type ('a, 'b) foo = { a : 'a; b : 'b; }

# let new_foo a b = {a; b};;
val new_foo : 'a -> 'b -> ('a, 'b) foo = <fun>

# let modify_a r new_a = { r with a = new_a };;
val modify_a : ('a, 'b) foo -> 'c -> ('c, 'b) foo = <fun>

# let modify_b r new_b = { r with b = new_b };;
val modify_b : ('a, 'b) foo -> 'c -> ('a, 'c) foo = <fun>

非正则递归类型。有趣的如果这确实是问题所在,那么OCaml不支持。。。具有对象上的语法,因为其类型系统无法为函数指定类型。这是因为OCaml不支持行类型变量,即:->'c->不能被类型化,我认为在最初的行中是可能的,这与OCaml缺乏对第一类行变量的支持无关。这是因为非正则类型递归必须经过数据构造函数。记录是数据构造函数,其中as对象是结构类型。对于类似的示例类型“a btree=Nil of”a | Succ of“a*”a btree可以,但不允许类型“a btree=[`Nil of”a | `Succ of“a*”a btree],因为多态变体是结构性的,
# type ('a, 'b) foo = { a: 'a; b: 'b };;
type ('a, 'b) foo = { a : 'a; b : 'b; }

# let new_foo a b = {a; b};;
val new_foo : 'a -> 'b -> ('a, 'b) foo = <fun>

# let modify_a r new_a = { r with a = new_a };;
val modify_a : ('a, 'b) foo -> 'c -> ('c, 'b) foo = <fun>

# let modify_b r new_b = { r with b = new_b };;
val modify_b : ('a, 'b) foo -> 'c -> ('a, 'c) foo = <fun>