Je discutais avec Sadek Drobi sur Twitter lorsque F # ne semblait pas supporter des types infinis. Il s'avère que dans C #, vous pouvez faire quelque chose dans ces lignes: Cependant, après une certaine expérimentation sur nos deux parties, nous avons déterminé que la même chose en F # semble impossible à la fois implicite et explicitement. < / p> explicite: strong> p> erreur FS0191: cette définition de type
implique une référence cyclique immédiate
à travers une abréviation, structure champ
ou relation héritage. p>
blockquote> implicite: strong> p> Mismatch de type. Attendre un 'b mais
donné un 'a ->' b. Le type résultant
serait infini lorsqu'il va unifier '' B '
et '' A -> 'B'. P>
blockQuote> Bien sûr, ce sont des échantillons intentionnellement simples. P> Je me demandais si je me trompe d'une manière ou d'une autre. J'ai peut-être manqué un certain type d'annotation nécessaire? P> p>
3 Réponses :
type d<'T> = delegate of 'T -> d<'T> //' let del : d<int> = null let anotherDel = del.Invoke(1).Invoke(2).Invoke(3) I think you need a named type that is representable directly in CLI to break the recursion, so in F# this means you need an actual delegate type as well.
Vous pouvez également faire quelque chose comme pour créer un type nommé par lequel effectuer la récursivité. Maintenant, cela fonctionne: P> let rec specialF = RecType (fun _ -> specialF)
Je serais également intéressé si la version la plus générale fonctionne: Stackoverflow.com/questions/1253374/...
Les types d'enregistrements récursifs doivent également fonctionner.
type A = { A : A } let rec a : A = { A = a }
Existe-t-il une application pratique ici, ou la question est-elle simplement résultant de l'enquête pour s'amuser?
Pour autant que je sache, il n'y a pas d'applications pratiques transparentes en référence. Cependant, un exemple serait qu'avec une sorte d'état mutable fermé, cela peut être utile pour des applications répétées. Ex: Ajoutez (1) (2) (3) (4) - où aucun nombre d'applications peut être effectué.
Voici un programme OCAML que j'ai écrit qui utilise cette fonctionnalité pour éviter un niveau d'indirection à l'aide de rectypes. ffconsultancy.com/languages/ray_tracer/code/1/ray.ml < / a>