Ce que j'essaie de construire est un arbre générique de syntaxe abstraite. Je suppose que j'ai un ensemble fixe de constructions syntaxiques et je définis un type F # pour chacun d'eux. Cependant, la représentation de par ex. Les noms d'identificateurs et les expressions doivent rester ouverts (génériques). Ainsi, le code ressemblera à quelque chose comme:Ce problème avec les modules (non) génériques en F #, encore
module GAST =
type Declaration<'Name, 'Expr> =
{
id: 'Name
initialValue: 'Expr
}
type Loop<'Name, 'Expr> =
{
condition: 'Expr
body: Statement<'Name, 'Expr> list
}
and Statement<'Name, 'Expr> =
| Declaration of Declaration<'Name, 'Expr>
...
| Loop of Loop<'Name, 'Expr>
...
Vous voyez le problème: j'ai beaucoup de types, tous paramétrés par 'Name
et 'Expr
. Quand je veux « instancier » mon AST générique à un AST spécifique que je devrais écrire un nouveau module où j'instancier chaque type individuel:
module SpecificAST =
type Name = string
type Expr = | Name of Name | Const of int | Addition of Expr * Expr
type Declaration = GAST.Declaration<Name, Expr>
type Loop = GAST.Loop<Name, Expr>
type Statement = GAST.Statement<Name, Expr>
Cela semble comme beaucoup de duplication de code, et crie quelque chose comme un module que vous pourriez passer des types comme arguments, parce que je veux vraiment quelque chose comme
module SpecificAST = GAST<Name, Expr>
ce qui précède n'est pas possible en F #. Lors de la recherche, j'ai trouvé Is it possible to pass parameters to F# modules? mais là le problème est différent. Il y a seulement une définition de type mais le comportement des fonctions de ce type est paramétré qui peut être résolu en transformant le type d'enregistrement en classe et en passant le comportement comme argument lors de l'instanciation.
J'ai aussi vu Can ML functors be fully encoded in .NET (C#/F#)? mais je ne voyais pas comment les différents liens pouvaient m'aider. Donc, ma question est la suivante: Étant donné plusieurs types génériques avec les mêmes paramètres de type. Puis-je instancier tout en même temps mais éviter une mauvaise duplication de code dans le module d'instanciation?
L'implémentation actuelle comporte deux arborescences, non typées et typées. Ils ont la même structure mais diffèrent dans la représentation des noms, des types et des expressions (langage source). Ils ont tous les deux des marcheurs (avant et après l'ordre) qui traversent la structure arborescente en exécutant certaines actions données. La question qui se posait était de savoir si les parties communes - la structure et ses marcheurs - pouvaient être unifiées.Ensuite, les arbres non typés et typés seraient simplement des instances du même AST avec des implémentations différentes pour les noms, les types et les expressions (langage source). D'où le design proposé. –
Bien sûr, la conception n'est pas la meilleure solution de toute façon, car je voudrais éventuellement jouer avec l'interface du serveur de langue des éditeurs. Pour cela, des parties des arbres devraient être recalculées en temps réel, ce qui nécessite probablement une configuration complètement différente. –