En fait il est faux que ocaml ne connaît pas le sous-typage, ce que veut dire BookeldOr c'est que ce sous-typage n'est jamais implicite. On m'a dit tout à l'heure qu'il n'était pas possible d'avoir à la fois le sous-typage implicite et l'inférence de types à la caml (je sais pas trop si c'est juste des questions de complexité d'algorithme ou si c'est plus profond que ça comme raisons). Mais tu as l'opérateur de coercition (je sais pas si on dit comme ça en français
) qui force à considérer la valeur du sous-type comme une valeur du super-type. Exemple :
# ([] :> int list);; - : int list = [] # ([1] :> 'a list);; - : int list = [1] # (`a :> [`a|`b]);; - : [ `a | `b ] = `aTiens intéressant le deuxième résultat. Ah ben oui, en fait tu peux considérer [ 1 ] comme une 'a list à condition que 'a soit égal à int en fait, donc 'a list est bien d'un certain point de vue un sous-type de int list, mais sauf que c'est seulement pour une certaine valeur de 'a, c'est pas le type 'a list avec la variable libre...
bon je réponds à l'autre question dans un autre post ^^
). En fait tout ce que tu fais quand tu passes dans un super-type c'est que tu oublies un certain nombre d'informations sur ta valeur. Mais là en l'occurrence il ne suffit pas d'oublier que 0 est un entier pour qu'il se transforme spontanément en flottant, il faut réellement le convertir, donc ça marche pas.
)
)
)
le problème dont tu parles est plutôt lié aux représentations : dans le cas où le type float est assez grand pour contenir tous les int, on peut changer de représentation au moment où on veut [potentiellement automatiquement] sans compromettre la sûreté, sinon effectivement le moment où le compilateur "choisit" de faire la conversion aura une influence sur le résultat, ce qui n'est pas glop du tout dans un système avec inférence de type [contrairement à un système où tous les types sont explicites et où ce genre de choses se "voit" et où c'est aussi explicite qu'un appel de fonction])
(i.e. une fonction acceptant un (float tree) pourrait avoir une version (really_a_float tree) et une version (int_disguised_as_float tree))
Et le typage c'est pas de la compilation ?
)
. Tu vois ? un record n'est pas du tout ce que tu crois, c'est quelque chose de beaucoup plus figé que ça... et donc pas question de sous-typage évidemment (le fait que tes champs a aient les mêmes noms ne fait pas qu'ils sont davantage compatibles pour ça). Bon les records ça a toujours été pourri hein... (enfin peut-être que si on maîtrise super bien le système de modules en fait c'est vachement utile dans certains cas, mais sinon c'est bel et bien pourri ^^) mais les classes ça fait exactement ce que tu veux (mais parfois il faut expliciter le sous-typage, comme je l'ai dit ; cf. fin du post)
c'est vrai que ça peut devenir une limitation pénible, si il faut passer son temps à caster manuellement vers le type voulu :/