È possibile utilizzare SYB per trasformare il tipo?
-
12-11-2019 - |
Domanda
Voglio scrivere un rename
funzione da sostituire String
nomi (che rappresentano identificatori gerarchici) nel mio AST
insieme a GUID
nomi (numeri interi) da una tabella dei simboli trasportati come stato nascosto in a Renamer
monade.
ho un AST a
Tipo che è parametrizzato sul tipo di nome. I nomi nelle foglie dell'AST sono di tipo Name a
:
data Name a = Name a
Il che rende facile colpirli con un trasformatore SYB.
Il parser viene digitato (ignorando la possibilità di errore per brevità):
parse :: String -> AST String
E voglio il rename
funzione da digitare:
rename :: AST String -> Renamer (AST GUID)
È possibile utilizzare SYB per trasformare tutto Name String
è in Name GUID
è con un trasformatore:
resolveName :: Name String -> Renamer (Name GUID)
e tutti gli altri valori da c String
a c GUID
Trasformando i loro figli e incollandoli indietro insieme allo stesso costruttore, anche se con un parametro di tipo diverso?
Il everywhereM
La funzione è vicina a quello che voglio, ma può solo trasformare c a -> m (c a)
e non c a -> m (c b)
.
La mia soluzione di fallback (oltre a scrivere la piastra caldaia a mano) è rimuovere il parametro del tipo AST
, e definisce Name
come questo:
data Name = StrName String
| GuidName GUID
in modo che il rinominato venga digitato:
rename :: AST -> Renamer AST
Fallo funzionare con everywhereM
. Tuttavia, ciò lascerebbe la possibilità che un AST
potrebbe ancora trattenere StrName
È dopo essere stato rinominato. Volevo usare il sistema di tipo per catturare formalmente il fatto che un rinominato AST
può solo trattenere GUID
nomi.
Nessuna soluzione corretta