Envoyé par
Tommy31
Comment "duck typing" et "statiquement et strictement typé" peuvent cohabiter ensemble ?
Je suis pas un pro d'ocaml, loin de là, mais je pensais que l'inférence de type rendait justement le duck typing impossible.
Tu as des exemples ? Ca m'intéresse.
Alors, disons qu'un canard, c'est un objet qui sait faire coincoin. Donc je peux utiliser un canard
1 2 3
| let utilise_canard c =
print_string "J'utilise un canard. ";
c#fait_coin_coin |
Ensuite tu peux définir un vrai canard
1 2 3 4 5
| class canard =
object
method fait_coin_coin = print_endline "Je suis un canard qui fait coin coin"
method envoler = print_endline "Je suis un canard et je m'envole"
end |
Mais tu peux aussi par exemple avoir un vélo qui fait coincoin quand il klaxonne
1 2 3 4 5
| class velo =
object
method fait_coin_coin = print_endline "Je suis un vélo qui fait coincoin quand il klaxonne"
method pedaler = print_endline "Je suis un vélo et je pédale"
end |
Et là tu peux utiliser les deux avec utiliser_canard
1 2 3 4 5 6 7
| let () =
let c = new canard in
let v = new velo in
utilise_canard c;
utilise_canard v;
v#pedaler;
c#envoler |
Avec comme output
1 2 3 4
| J'utilise un canard. Je suis un canard qui fait coin coin
J'utilise un canard. Je suis un vélo qui fait coincoin quand il klaxonne
Je suis un vélo et je pédale
Je suis un canard et je m'envole |
Donc voilà, duck typing !
Pourtant, tout ça est bien statiquement typé. La première fonction a comme type
val utilise_canard : < fait_coin_coin : 'a; .. > -> 'a = <fun>
ce qui signifie "je suis une fonction qui attend un objet qui a au minimum une méthode 'fait_coin_coin' qui retourne un certain type, et je retourne ce même type"
D'ailleurs, on peut ajouter une classe avec un type de retour différent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class canard_compteur =
object
val mutable count = 0
method fait_coin_coin =
count <- count + 1;
Printf.printf "Je suis un canard qui a fait coin coin %i fois\n" count;
count
method envoler = print_endline "Je suis un canard et je m'envole"
end
let () =
let cc = new canard_compteur in
ignore (cc#fait_coin_coin);
ignore (utilise_canard cc);
let i = utilise_canard cc in
Printf.printf "Le canard a fait coin coin %i fois\n" i |
avec comme sortie
1 2 3 4
| Je suis un canard qui a fait coin coin 1 fois
J'utilise un canard. Je suis un canard qui a fait coin coin 2 fois
J'utilise un canard. Je suis un canard qui a fait coin coin 3 fois
Le canard a fait coin coin 3 fois |
Voilà voilà
Partager