Function argument polymorphism

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?

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 Likes

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

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.

6 Likes