Function argument polymorphism


#1

For example I have two different record types, like:

   type rec1 = {
       prop1 : int;
       prop2 : int;
       prop3 : int;
       prop3 : int;
   }
   type rec2 = {
       prop4 : int;
       prop2 : int;
       prop3 : int;
       prop5 : int;
   }

where they have prop2 and prop3 in common, but rest is different.
And I want to write a function which takes an argument of type rec1 or rec2 and uses only prop2 and prop3 from them. But I don’t want to duplicate a code if create two different functions for different argument types. And creating a sum type is not an option. Are there any more ways to achieve that?


#2

OCaml functions aren’t allowed to be polymorphic over record fields this way. However, this kind of polymorphism is a classic use case for objects! Instead of records you can create two objects:

let rec1 =
  object
    method prop1 = 1
    method prop3 = 2
  end
let rec2 =
  object
    method prop2 = 3
    method prop3 = 4
  end
let func r = r#prop3
let x = func rec1
let y = func rec2

If you check the types you’ll see that func is polymorphic, and accepts any object with a prop3 method:

val func : < prop3 : 'a; .. > -> 'a


#3

Interesting, thank you! A bit inconsistent for my taste - such drastic difference in handling them.


#4

If you’re interested, the theorey for how to add this kind of polymorphism to an ML like language while keeping decidable type inference has recently been worked out:
https://www.cl.cam.ac.uk/~sd601/mlsub/

It’s more complicated than you might imagine at first. This was an open problem for quite a while.