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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top