В "Безопасный общий доступ" в Haskell Энди Гилл показывает, как восстановить общий доступ, существовавший на уровне Haskell, в DSL. Его решение реализовано в пакете data-reify. Можно ли изменить этот подход для работы с GADT? Например, учитывая этот 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
Я хотел бы восстановить совместное использование, изменив вышеуказанный AST на
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
посредством функции
recoverSharing :: Ast -> (Map Name, Ast2 e1, Ast2 e2)
(Я не уверен в типе recoverSharing
.)
Обратите внимание, что я не забочусь о введении новых привязок через конструкцию let, но только в восстановлении обмена, существовавшего на уровне Haskell. Вот почему я recoverSharing
вернул a Map
.
Если это невозможно сделать как многоразовый пакет, можно ли это сделать, по крайней мере, для конкретного GADT?