Ich habe versucht, das Papier zu lesen (http://www.ittc.ku.edu/csdl/fpg/sites/default/files/Gill-09-TypeSafeReification.pdf) und es geschafft, meinen symbolischen Ausdruckstyp zu verifizieren, aber ich kann nicht herausfinden, wie man eine Liste von ihnen wieder herstellt. Hier ist der vereinfachte Code:Wie man eine Liste von Daten mit Data.Reify wieder herstellt?
{-# OPTIONS_GHC -Wall #-}
{-# Language TypeOperators #-}
{-# Language TypeFamilies #-}
{-# Language FlexibleInstances #-}
import Control.Applicative
import Data.Reify
-- symbolic expression type
data Expr a = EConst a
| EBin (Expr a) (Expr a)
deriving Show
-- corresponding node type
data GraphExpr a b = GConst a
| GBin b b
deriving Show
instance MuRef (Expr a) where
type DeRef (Expr a) = GraphExpr a
mapDeRef _ (EConst c) = pure (GConst c)
mapDeRef f (EBin u v) = GBin <$> f u <*> f v
-- this works as expected
main :: IO()
main = reifyGraph (EBin x (EBin x y)) >>= print
where
x = EConst "x"
y = EConst "y"
-- (output: "let [(1,GBin 2 3),(3,GBin 2 4),(4,GConst "y"),(2,GConst "x")] in 1")
-- but what if I want to reify a list of Exprs?
data ExprList a = ExprList [Expr a]
data GraphList a b = GraphList [GraphExpr a b]
instance MuRef (ExprList a) where
type DeRef (ExprList a) = GraphList a
-- mapDeRef f (ExprList xs) = ???????
Ich weiß nicht, was Sie mit dem einmaligen Kombinator meinen. Bedeutet dies, dass, wenn ich einen gemeinsamen Zwischenknoten habe, der in zwei Ausgaben erscheint, meine einzige Option ist, retifyGraph an beiden Ausgaben auszuführen und dann explizite CSE mit einer Hash-Datei oder etwas zu tun? Ist das eine Einschränkung von reifyGraph oder StablePtr? – ghorn
Nun, retifyGraph ist nur für die monomorphe Rekursion gedacht. Hier müssen Sie polymorph in die Ausdrücke rekurrieren. Es gibt nichts, was die Erstellung eines Kombinators in data-retify wirklich stoppt, der diese Art von Dienst bereitstellt, aber es gibt keinen da. –