输入ocaml方法

时间:2013-05-23 01:29:26

标签: ocaml

我正在玩方法重新定义,我发现了这个愚蠢的例子:

class a =
object 
    method get (x : a) = x
end

class b =
object
    inherit a
    method get (x : b) = x
end

我明确指出我希望b类中的get方法取b并返回b,但方法签名是 - >一个。如果我这样做     (新b)#get(新a) 当他真的不应该,他很开心。在那之后我添加了一些愚蠢的东西:

class a =
object 
    method get (x : a) = x
end

class b =
object
    inherit a
    method get (x : b) = x#foo(x)
    method foo (x : a) = x
end

我得到Error: This expression has type b It has no method foo

究竟发生了什么?

1 个答案:

答案 0 :(得分:5)

首先采用第一个例子:OCaml具有对象的结构类型,而不是标称类型。换句话说,对象的类型完全由其方法(及其类型)决定。因此,类ab实际上是同一类型。

$ ocaml
        OCaml version 4.00.0

# class a = object method get (x: a) = x end;;
class a : object method get : a -> a end
# class b = object inherit a method get (x: b) = x end;;
class b : object method get : a -> a end
# let a0 = new a;;
val a0 : a = <obj>
# let b0 = new b;;
val b0 : b = <obj>
# (a0: b);;
- : b = <obj>
# (a0: a);;
- : a = <obj>
# (b0: a);;
- : a = <obj>
# (b0: b);;
- : b = <obj>
# 

(我在此处展示的是,a0b0都属于a 类型{em}和类型b。 )

在第二个例子中,我要说你试图给get方法一个新类型。在OCaml中覆盖方法时,参数和返回类型必须与父类中的相同。

错误消息似乎很不幸。我的猜测是,编译器认为b类型是类型a的另一个名称。

OCaml的优势之一是它会推断类型。如果您在课程: b中取消get参数b,则会收到以下错误:

This expression has type a. It has no method foo

这有点帮助,因为它显示(我认为)您需要为参数设置a类型。

副评论(原谅我):如果你从主流OO语言来到OCaml的OO部分,它可能会让你感到奇怪。但是如果你首先学习OCaml的FP部分,你可能会想知道为什么所有主流的OO语言都会出现这么多错误:-)。 (当然,一切都是权衡,并且没有一种正确的方法来计算结构。但是OCaml的OO子系统正在做一些相当令人印象深刻的事情。)