Evitar repetitivo al tratar con muchos tipos no relacionados
Estoy escribiendo código que trata con valores deLanguage.Exts.Annotated.Syntax, donde se definen una variedad de tipos que reflejan la estructura de un módulo de Haskell:
data Module l = ...
data Decl l = ...
data Exp t = ...
-- etc
Me gustaría poder escribir funciones que guíen estas estructuras de datos y realicen 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 unTree
Tipo que envuelve cada uno de estos tipos para que mi función de transformación pueda hacerlo.Tree l -> Tree l
:
data Tree l = ModuleT (Module l)
| DeclT (Decl l)
| ExpT (Exp l)
-- etc copy & paste
Sin embargo, ahora me estoy escribiendo un montón de código que toma unModule
, lo envuelveModuleT
, llama a una función, luego devuelve el resultado aModule
otra vez. Yo 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 en Language.Exts.Annotated.Syntax, ¿lo estoy haciendo de forma incorrecta?Si no es así, ¿puedo reducir de alguna manera todo esto?