estoy escribiendo código que se ocupa de los valores de Language.Exts.Annotated.Syntax, donde se define una variedad de tipos que reflejan la estructura de un módulo de Haskell:repetitivo cuando se trata de muchos tipos no relacionados
data Module l = ...
data Decl l = ...
data Exp t = ...
-- etc
me gustaría para poder escribir funciones que recorren estas estructuras de datos y realizar varias transformaciones en ellas. Como no hay un tipo de datos común, no puedo escribir una función que haga todo.
Hasta ahora he escrito un tipo Tree
que envuelve cada uno de estos tipos para que mi función de transformación puede hacer Tree l -> Tree l
:
data Tree l = ModuleT (Module l)
| DeclT (Decl l)
| ExpT (Exp l)
-- etc copy & paste
Sin embargo ahora estoy encontrando a mí mismo escribiendo un montón de código que toma una Module
, lo envuelve ModuleT
, llama a una función y luego vuelve a desenvolver el resultado en Module
. Tengo:
class AnnotatedTree ast where
tree :: ast l -> Tree l
untree :: Tree l -> ast l
instance AnnotatedTree Module where
tree = ModuleT
untree (ModuleT x) = x
untree _ = error "expected ModuleT"
-- etc ad nauseam
Dos preguntas:
- Dado que no puedo cambiar los tipos de Language.Exts.Annotated.Syntax, lo voy de este por el camino equivocado?
- Si no, ¿puedo reducir todo este texto estándar de alguna manera?
uniplate parece justo lo que necesitaba, gracias. Ahora he eliminado mi repetición. –
Con este enfoque ya no necesitas realmente tu tipo de árbol, ¿o sí? – Martijn
Así es, yo no; Puedo configurar mis funciones de reescritura de árboles como una serie de aplicaciones rewriteBi, una para cada tipo que me interesa. –