Est-il possible d'utiliser SYB pour transformer le type?
-
12-11-2019 - |
Question
Je veux écrire un rename
fonction à remplacer String
noms (qui représentent des identifiants hiérarchiques) dans mon AST
avec GUID
Noms (entiers) d'une table de symboles transportée comme état caché dans un Renamer
Monade.
j'ai un AST a
Type qui est paramétré sur le type de nom. Les noms dans les feuilles de l'AST sont de type Name a
:
data Name a = Name a
Ce qui facilite les cibler avec un transformateur SYB.
L'analyseur est dactylographié (ignorant la possibilité d'erreur pour la concision):
parse :: String -> AST String
Et je veux le rename
fonction à saisir:
rename :: AST String -> Renamer (AST GUID)
Est-il possible d'utiliser SYB pour transformer tout Name String
dans Name GUID
avec un transformateur:
resolveName :: Name String -> Renamer (Name GUID)
Et toutes les autres valeurs de c String
à c GUID
En transformant leurs enfants et en les collant avec le même constructeur, bien qu'avec un paramètre de type différent?
La everywhereM
La fonction est proche de ce que je veux, mais il ne peut que se transformer c a -> m (c a)
et pas c a -> m (c b)
.
Ma solution de secours (autre que d'écrire la chauffe-plaque à la main) consiste à supprimer le paramètre de type de AST
, et définir Name
comme ça:
data Name = StrName String
| GuidName GUID
Pour que le renommée soit tapée:
rename :: AST -> Renamer AST
Le faire fonctionner avec everywhereM
. Cependant, cela laisserait la possibilité qu'un AST
pourrait encore tenir StrName
a été renommé. Je voulais utiliser le système de type pour capturer officiellement le fait qu'un AST
ne peut tenir que GUID
des noms.
Pas de solution correcte