How to write transform one set of ADTs to another with SYB?
More specifically, I want to transform a tree of SomeExpr to a tree of (SomethingElse, SomeExpr), "prefixing" each node with a default value in the process. The result have essentially the same structure as the input. data ASTAttachment = AA {} deriving (Eq,Read,Show,Ord,Typeable,Data) type family AST a :: * type instance AST () = ASTExpr () type instance AST AA = (AA, ASTExpr AA) data ASTExpr a = ALiteral String | AApplication [AST a] (ASTOp a) | ARef String | ABind (AST a) String | AMany (ASTMany a) data ASTOp a = AOSym String | AOAlpha String | AOMany (ASTMany a) data ASTMany a = AMSimple [AST a] | AMAggeregate [AST a] deriving instance Typeable ASTMany deriving instance Typeable ASTOp deriving instance Typeable ASTExpr deriving instance Data (ASTMany ()) deriving instance Data (ASTOp ()) deriving instance Data (ASTExpr ()) Currently I have values of type (AST ()), and I need to transform them to (AST ASTAttachment) in the obvious way. Now I'm stuck at "derive instance Data (ASTExpr ASTAttachment)", where ghc reports "Multiple declarations of '$cSomeConstructor'". Even if I can get past this, I still don't know how to use SYB to transform between trees of different types.
Hi Ducis, Did you mean: "data AA = AA" when you write "data ASTAttachment = AA"? In any case, you can write Data instances that cover (ASTExpr AA) and (ASTExpr ()) with: deriving instance (Data t, Data (AST t)) => Data (ASTMany t) deriving instance (Data t, Data (AST t)) => Data (ASTOp t) deriving instance (Data t, Data (AST t)) => Data (ASTExpr t) As for writing a f :: (Data (t AA), Data (t ())) => t () -> t AA where t could be ASTExpr, it might help to look at the two options here: http://www.haskell.org/haskellwiki/Scrap_your_boilerplate#fmap Regards, Adam On Sat, Aug 23, 2014 at 10:24 AM, ducis <ducis_cn@126.com> wrote:
More specifically, I want to transform a tree of SomeExpr to a tree of (SomethingElse, SomeExpr), "prefixing" each node with a default value in the process. The result have essentially the same structure as the input.
data ASTAttachment = AA {} deriving (Eq,Read,Show,Ord,Typeable,Data) type family AST a :: * type instance AST () = ASTExpr () type instance AST AA = (AA, ASTExpr AA) data ASTExpr a = ALiteral String | AApplication [AST a] (ASTOp a) | ARef String | ABind (AST a) String | AMany (ASTMany a) data ASTOp a = AOSym String | AOAlpha String | AOMany (ASTMany a) data ASTMany a = AMSimple [AST a] | AMAggeregate [AST a] deriving instance Typeable ASTMany deriving instance Typeable ASTOp deriving instance Typeable ASTExpr deriving instance Data (ASTMany ()) deriving instance Data (ASTOp ()) deriving instance Data (ASTExpr ())
Currently I have values of type (AST ()), and I need to transform them to (AST ASTAttachment) in the obvious way. Now I'm stuck at "derive instance Data (ASTExpr ASTAttachment)", where ghc reports "Multiple declarations of '$cSomeConstructor'". Even if I can get past this, I still don't know how to use SYB to transform between trees of different types.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (2)
-
adam vogt -
ducis