views:

131

answers:

2

I am learning about OCaml's OOP constructs and partially implemented this today until I realized I have no idea how to represent a polymorphic match statement without using the type keyword outside of the object.

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;;

Is it possible to determine the type of object passed in on-the-fly?

+3  A: 

That match isn't doing anything but binding 'param' to 'string', ocaml should say that the second match isn't used. I believe you'll have to use variant types to do the matching. Below is an example using polymorphic variant types.

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)
nlucaroni
+1  A: 

In general, OCaml does not support run-time identification of types.

That said, there is a little type information embedded in the runtime representation to let the garbage collector work. To determine if something is a string, you can do:

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

More information on OCaml's runtime representation is available in Interfacing C with Objective Caml. However, these kinds of checks generally run counter to the the kinds of programming OCaml encourages, and it is not clear how you would do anything useful with this particular check (you'll need to convert to a string, and are wreaking havoc on type safety). A far better solution is to use an algebraic data type or polymorphic variants to describe the valid parameter types and pattern-match over that.

Type-safe downcasts could be useful but indeed are not supported by OCaml. You'll need to roll your own mechanism (or, better, design around it) if that is what you are looking for.

Michael E