Le type
est
lu `objet qui contient au moins la méthode
getx de type int.
# let f(p) = p#getx + 1;; val f : < getx : int; .. > -> int = <fun>La fonction f, dont l'argument possède un tel type, est clairement polymorphe car elle peut recevoir des objets d'une infinité de types: tous ceux qui possèdent au moins une composante getx de type int. Les types ouverts autorisent une forme de polymorphisme paramétrique. En effet, pour le typeur Ocaml, le type de f est:
qui est le type des fonctions qui admettent les points en
argument! Le type de f est polymorphe paramétrique: il possède
la variable de type ,
et on autorise l'utilisation de f
via l'instantiation
de cette variable.
Considérons maintenant la fonction:
let origin(p : point) = p#getx = 0;; val origin: point -> bool = <fun>
La notation point est celle d'un type fermé et donc origin est une fonction monomorphe: elle n'accepte que des objets qui ont exactement la même structure que les points.
#let cp = new colorpoint 3 "rouge";; val cp : colorpoint = <obj> # origin(cp);; This expression has type colorpoint = < getx : int; move : int -> unit; getcolor : string; setcolor : string -> unit > but is here used with type point = < getx : int; move : int -> unit >
Pour rendre cette fonction polymorphe paramétrique, on doit employer la notation p:# point associée aux types ouverts:
# let origin2 (p : #point) = p#getx = 0;; val origin2 : #point -> bool = <fun>et maintenant on peut l'appliquer aux points colorés
# let p = new point 2;; val p : point = <obj> # origin2 (p);; - : bool = false # origin2 (cp);; - : bool = false