dans F #, j'aimerais avoir ce que je vois comme un type de données abstrait abstrait assez standard: En d'autres termes, le code à l'intérieur du module sait que my_type est un int, mais code à l'extérieur ne le fait pas. Toutefois, F # semble avoir une restriction où les abréviations de type ne peuvent spécifiquement pas être cachées par une signature. Ce code donne une erreur de compilateur et la restriction est décrite Ici . P> Si mon_type était plutôt une union discriminée, il n'y a pas d'erreur de compilateur. Ma question est que la restriction? Je semble que je me souvienne de pouvoir faire cela dans SML et OCAML, et en outre, n'est-ce pas une jolie chose standard à faire lors de la création d'un type de données abstraite? P> Merci P> P>
4 Réponses :
De ce que je comprends, F # ne permet pas une abréviation d'être cachée par une signature. p>
J'ai trouvé ce lien où le blogueur a commenté sur ceci mais je ne suis pas sûr de les détails de la raison pour laquelle c'est le cas. P>
Mon hypothèse est qu'il s'agit d'une restriction définie pour permettre une interporation plus efficace avec d'autres langues sur le CLR. P>
Notez que vous pouvez définir une abréviation de type comme privée dans un module:
// File1.fs module File1 type private MyType = int let e : MyType = 42 let f (x:MyType) = x+1 // Program.fs module Program do printfn "%A" (File1.f File1.e)
Vrai, mais le sens dans lequel j'imaginais un ADT permet aux clients de savoir sur le type, mais pas sa représentation. Si j'ai une autre fonction dans File1, laissez vide (): mytype = 1 Puis-je appeler cette fonction de l'extérieur du fichier1 et transmettre son résultat à F?
Oui (j'ai édité l'exemple ci-dessus). Mais je vois ton point, c'est klutzy, comme par exemple. File1.MyType n'apparaît pas comme une entité dans la liste IntelliSense, bien que FILE1.MYTYPE apparaisse dans les signatures de F et E.
Notez que cela ne vous empêche pas de faire quelque chose comme file1.f 42 code> de l'extérieur du module, les informations que
mytype = int code> n'est pas vraiment cachée. Si malheureusement, cela n'atteint pas l'effet souhaité.
Tapez les abréviations de type dans F # sont compilées (c'est-à-dire que le code compilé utilisera int code>, pas
mytype code>), de sorte que vous ne pouvez donc pas les faire abstraite correctement. En théorie, le compilateur pourrait appliquer l'abstraction au sein du monde F #, mais cela ne serait pas très utile car il pourrait toujours fuir dans d'autres langues. P>
Comme le souligne Ganesh, il s'agit d'une limitation technique du compilateur F # (et d'exécution .NET), car l'abréviation de type est simplement remplacée par le type réel pendant la compilation. En conséquence, si vous écrivez une fonction:
type MyType = MT of int let foo (MT a) = MT(a + 1)
Ouais, merci Tomas et Ganesh aussi. Je comprends maintenant la question et je peux voir que, compte tenu de cette stratégie de compilation, cette question est une conséquence. C'est un peu décevant depuis que je travaille presque entièrement dans l'espace F # mais je sais que l'interopérabilité est très importante, donc je ne me plaingais pas! :-)