6
votes

F #: ne peut pas cacher une abréviation de type dans une signature? Pourquoi pas?

dans F #, j'aimerais avoir ce que je vois comme un type de données abstrait abstrait assez standard: xxx

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 .

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?

Merci

f#

0 commentaires

4 Réponses :


1
votes

De ce que je comprends, F # ne permet pas une abréviation d'être cachée par une signature.

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.

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.


0 commentaires

4
votes

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)


3 commentaires

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 de l'extérieur du module, les informations que mytype = int n'est pas vraiment cachée. Si malheureusement, cela n'atteint pas l'effet souhaité.



5
votes

Tapez les abréviations de type dans F # sont compilées (c'est-à-dire que le code compilé utilisera int , pas mytype ), 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.


0 commentaires

10
votes

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)


1 commentaires

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! :-)