Wie kann ich die Freigabe in einem GADT wiederherstellen?

ImTypensichere beobachtbare Freigabe in Haskell Andy Gill zeigt, wie Sie die auf Haskell-Ebene vorhandene gemeinsame Nutzung in einem DSL wiederherstellen können. Seine Lösung ist in der implementiertDaten-Reify-Paket. Kann dieser Ansatz geändert werden, um mit GADTs zu arbeiten? Beispiel für dieses 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

Ich möchte das Teilen wiederherstellen, indem ich den obigen AST in umwandle

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

durch eine Funktion

recoverSharing :: Ast -> (Map Name, Ast2 e1, Ast2 e2)

(Ich bin mir nicht sicher über die Art vonrecoverSharing.)

Beachten Sie, dass es mir nicht wichtig ist, neue Bindungen über ein let-Konstrukt einzuführen, sondern nur, die auf der Haskell-Ebene vorhandene Freigabe wiederherzustellen. Deshalb habe ichrecoverSharing zurück aMap.

Wenn es nicht als wiederverwendbares Paket ausgeführt werden kann, kann es zumindest für ein bestimmtes GADT ausgeführt werden?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage