Tutorial :Determining type on the fly in OCaml's OOP construct



Question:

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?


Solution:1

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)  


Solution:2

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.


Solution:3

The idea of a polymorphic match statement contradicts the very idea of object-oriented programming! Customisation of behaviour should be encapsulated in objects, this is what they are for. Code asking a class “what are you, actually” signals a design problem.

That said, if you really want classes to be able to tell you what they actually are, the easiest way is to just add a method for this:

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  

Do not use polymorphic variants for this, as you break the advantage of exhaustive pattern matchings in maintenance operations.

Again, if you do so, you are likely ignoring the Liskov substitution principle and preparing busy days for the maintenance officer of your code. Our world does not need that cruelty!


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »