class - What's the proper way to make an Ocaml subclass with additional methods? -


in ocaml i'm struggling subclassing , types:

class super =     object (self)     method doit =        ...   end;    class sub =     object (self)     inherit super     method doit =        ...       self#somethingelse       ...      method somethingelse =       ...   end;    let myfunction (s:super) =     ...    myfunction new sub 

apparently in ocaml, class sub not "subtype" of class super, because sub#doit method calls method in sub not present in super. however, seems pretty common use-case oo programming. recommended way accomplish this?

as mentioned rémi, problem code ocaml type system supports 1 type per expression: expression of type sub not of type super. in example, myfunction expects argument of type super, , expression new sub of type sub, hence issue.

upcasting essential object-oriented programming, , ocaml support 2 distinct constructs.

the first type coercion. if super supertype of sub (meaning semantically, values of type sub behave values of super), , x : sub, (x :> super) : super. :> type operator makes conversion explicit — equivalent of popular object-oriented languages implicitly when use avalue of type subwhere superis expected.

the second supertype constraints: requiring given type variable subtype of given type. written #super or (#super 'a) if wish name type variable within. supertype constraints don't change type of expression type coercion does, merely check type valid subtype of required type.

to become more aware of difference, consider following example:

class with_size ~size = object    val size    = size : int   method size = size end  class person ~name ~size = object   inherit with_size ~size   val name    = name : string   method name = name end  let pick_smallest_coerce (a : with_size) (b : with_size) =    if # size < b # size else b  let pick_smallest_subtype (a : #with_size) (b : #with_size) =    if # size < b # size else b 

the type of pic_smallest_coerce with_size -> with_size -> with_size: if passed 2 person instances, return value of type with_size , not able call name method.

the type of pic_smallest_subtype (#with_size 'a) -> 'a -> 'a: if pass 2 person instances, type system determine 'a = person , correctly identify return value being of type person (which lets use name method).

in short, supertype constraints merely make sure code run, without losing type information @ all — variable retains original type. type coercion loses type information (which, in absence of down-casting, nasty thing), it should used last resort in 2 situations:

1. cannot have polymorphic function. supertype constraints rely on #super being free type variable, if cannot afford have free type variable in code, have without it.

2. need store values of different actual types in same container. list or reference can contain either person or box instances use with_size , coercion:

let things = [ my_person :> with_size ; my_box :> with_size ] 

do note type inference algorithm discover supertype constraints on own (it not determine class or class type intended use, construct literal class type):

let pick_smallest_infer b =    if # size < b # size else b  val pick_smallest_infer : (< size : 'a ; .. > 'b) -> 'b -> 'b 

as such, rare exceptions, annotating actual supertype constraints useful exercise when documenting code.


Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -