有许多Haskell
教程将源解析为AST,AST重写,AST评估,但没有关于两个AST之间的映射。有没有"规范"在transformFoo2Bar
中实施Haskell
的方式?
type FooIdentifier = String
data Foo = Foo FooIdentifier [FooMethod] deriving (Show)
data FooMethod = FooMethod FooIdentifier [FooExpression] deriving (Show)
data FooExpression = FooAB FooIdentifier FooIdentifier | FooZ FooIdentifier deriving (Show)
type BarIdentifier = String
type BarLabel = String
data Bar = Bar BarIdentifier [BarExpression] deriving (Show)
data BarExpression = BarA BarIdentifier BarIdentifier
| BarB BarIdentifier BarIdentifier | BarZ BarIdentifier deriving (Show)
--
-- transformFoo2Bar [Foo "foo" [FooMethod "foo1" [FooAB "a" "b", FooZ "z"], FooMethod "foo2" [FooZ "z"]]]
--
-- to evaluate to
--
-- [Bar "foo_foo1" [BarA "a" "b", BarB "a" "b", BarZ "z"], Bar "foo_foo2" [BarZ "z"]]
--
transformFoo2Bar :: [Foo] -> [Bar]
transformFoo2Bar = undefined
与代码编译类似,但不是发出编译代码,而是将结果保存为AST。
也可以将这些映射中的一些重用作反向映射吗?
由于
答案 0 :(得分:1)
非常不正常这样做的方法是将BarExpression的定义更改为
data BarExpression = BarB BarIdentifier | BarA BarIdentifier BarIdentifier deriving (Show)
这样它不仅在结构上类似于FooExpression
,而且具有相同的运行时表示。
然后您可以使用Unsafe.Coerce.unsafeCoerce
:
fe1 = FooA "a"
fe2 = FooB "x" "y"
fm1= FooMethod "meth1" [fe1,fe2]
foo1 = Foo "foo" [fm1]
允许你这样做
ghci> unsafeCoerce foo1 :: Bar
Bar "foo" [BarProc "meth1" [BarB "a",BarA "x" "y"]]
<font size+=1000 color="red"><blink>
</blink></font>
我不建议这样做,因为它会让你的永恒的灵魂处于危险之中,一看到它就会意外地突破,并以非常非常糟糕的方式(如果你不交换) BarExpression
此示例开始导致段错误:-)但它适用于此特定用例。
或者,您可以摆脱其中一种同构类型;你有什么理由不这样做吗?