4

我正在学习 OCaml 的 OOP 结构并在今天部分实现,直到我意识到我不知道如何在不使用对象外部的 type 关键字的情况下表示多态匹配语句。

class bar (param:string) =
object (code)

end;;

class foo param =
object (code)
 initializer 
  match param with
   string -> Printf.printf "param is a string"
   | bar -> Printf.printf "param is a bar"     
end;;

let b = new bar "a string";;
let f1 = new foo "test";;
let f2 = new foo b;;

是否可以即时确定传入的对象类型?

4

3 回答 3

3

那个匹配除了将'param'绑定到'string'之外什么也没做,ocaml应该说第二个匹配没有被使用。我相信您必须使用变体类型来进行匹配。下面是一个使用多态变体类型的示例。

class bar (param:string) =
  object (code)
end

class foo param =
  object (code)
  initializer 
    match param with
    | `String str -> Printf.printf "param is a string"
    | `Bar bar -> Printf.printf "param is a bar"     
end

let b = new bar "a string"
let f1 = new foo (`String "test")
let f2 = new foo (`Bar b)
于 2009-03-11T15:05:37.710 回答
3

通常,OCaml 不支持类型的运行时识别。

也就是说,运行时表示中嵌入了一些类型信息,以让垃圾收集器工作。要确定某物是否为字符串,您可以执行以下操作:

if Obj.tag (Obj.repr param) = Obj.string_tag then

有关 OCaml 运行时表示的更多信息,请参见Interface C with Objective Caml。但是,这些类型的检查通常与 OCaml 鼓励的编程类型背道而驰,并且不清楚您将如何使用此特定检查做任何有用的事情(您需要转换为字符串,并且对类型造成严重破坏安全)。一个更好的解决方案是使用代数数据类型或多态变量来描述有效的参数类型和模式匹配。

类型安全的向下转换可能很有用,但 OCaml 确实不支持。如果这是您正在寻找的,您将需要推出自己的机制(或者更好地围绕它进行设计)。

于 2010-10-29T19:31:22.630 回答
0

多态匹配语句的想法与面向对象编程的想法相矛盾!行为的定制应该封装在对象中,这就是它们的用途。代码问一个类“你是什么,实际上”表示设计问题。

也就是说,如果你真的希望类能够告诉你它们实际上是什么,最简单的方法就是为此添加一个方法:

type typ = A | B

class bar =
object
  method typ = A
end

class rebar =
object
  method typ = B
end

class foo param =
object
   initializer
   match param#typ with
   | A -> print_endline "This is a A"
   | B -> print_endline "This is a B"
end

不要为此使用多态变体,因为您会破坏维护操作中详尽模式匹配的优势。

同样,如果您这样做,您可能会忽略Liskov 替换原则,并为您的代码维护人员准备忙碌的日子。我们的世界不需要那种残酷!

于 2016-01-29T17:54:33.160 回答