Como posso recuperar o compartilhamento em um GADT?
EmCompartilhamento observável de tipo seguro em Haskell Andy Gill mostra como recuperar o compartilhamento que existia no nível Haskell, em uma DSL. Sua solução é implementada nopacote de reificação de dados. Essa abordagem pode ser modificada para funcionar com os GADTs? Por exemplo, dado este GADT:
data Ast e where
IntLit :: Int -> Ast Int
Add :: Ast Int -> Ast Int -> Ast Int
BoolLit :: Bool -> Ast Bool
IfThenElse :: Ast Bool -> Ast e -> Ast e -> Ast e
Gostaria de recuperar o compartilhamento, transformando a AST acima em
type Name = Unique
data Ast2 e where
IntLit2 :: Int -> Ast2 Int
Add2 :: Ast2 Int -> Ast2 Int -> Ast2 Int
BoolLit2 :: Bool -> Ast2 Bool
IfThenElse2 :: Ast2 Bool -> Ast2 e -> Ast2 e -> Ast2 e
Var :: Name -> Ast2 e
a propósito de uma função
recoverSharing :: Ast -> (Map Name, Ast2 e1, Ast2 e2)
(Eu não tenho certeza sobre o tipo derecoverSharing
.)
Note que eu não me importo em introduzir novas ligações através de uma construção let, mas apenas em recuperar o compartilhamento que existia no nível Haskell. É por isso que tenhorecoverSharing
devolver umMap
.
Se não puder ser feito como um pacote reutilizável, pelo menos pode ser feito para um GADT específico?