I had the same problem and I found a solution using data-reify.
What you need to understand in order to arrive at a solution is the following: 1. Even if the EDSL does not have lists, the type of graph may contain them 2. You can believe different data types into the same type of result.
So, we start by adding list constructors to our result type:
data GraphExpr a b = GConst a
| GBin b b
| Cons b b
| Nil
deriving Show
MuRef, Expr a GraphExpr.
instance MuRef [Expr a] where
type DeRef [Expr a] = GraphExpr a
mapDeRef _ [] = pure Nil
mapDeRef f (x:xs) = Cons <$> f x <*> f xs
,
reified = reifyGraph [EBin x (EBin x y), Ebin y (EBin x y)]
where x = EConst "x"
y = EConst "y"
let [(1,Cons 2 6),(6,Cons 7 9),(9,Nil),(7,GBin 5 8),(8,GBin 3 5),(2,GBin 3 4),(4,GBin 3 5),(5,GConst "y"),(3,GConst "x")] in 1
reified node -ids , Conses node -ids .
walkConses :: Graph (GraphExpr t) -> [Unique]
walkConses (Graph xs root) = go (lookup root xs)
where
go (Just (Cons n1 n2)) = n1 : go (lookup n2 xs)
go (Just Nil) = []
( , IntMap )
, , DAG Cons- node ( ), , node -ids xs node -ids .
, walkConses , :
[2, 7]
, , .