【发布时间】:2018-06-11 03:20:59
【问题描述】:
我需要对 AST 进行转换;这是 AST 的一部分:
data Expr
= BinExpr { beOp :: BinaryOp
, beLeft :: Expr
, beRight :: Expr }
| Name Text
| IntegerLit Integer
| StringLit Text
deriving (Data, Typeable)
这是一个相当复杂的 AST,所以涉及的类型很多。
我正在使用alloy 来生成通用转换,具体来说:
autoGen :: IO ()
autoGen = do
createDirectoryIfMissing True baseDir
writeInstancesTo inst doc imports targetFile
where
inst = allInstances GenWithoutOverlapped
doc = [genInstance (undefined :: Doc)]
imports = header ++ instanceImports
现在,使用 String 时这很好,但我正在尝试迁移到 Data.Text。当代码生成运行时,它会像这样读取 Data.Text 的内部:
instance (Alloy ([(GHC.Types.Char)]) (f :- ops) BaseOp) =>
Alloy ((Data.Text.Internal.Text)) BaseOp (f :- ops) where
transform _ ops (Data.Text.Internal.pack a0)
= Data.Text.Internal.pack
(transform ops BaseOp (a0))
我相信pack 与 GHC 内部结构相关联,因此这不是有效的模式匹配,无论如何,将代码与 Data.Text 的内部结构相混淆很可能会破坏不变量。 (编辑:看起来有一个 instance Data Text where gfoldl f z txt = z packf(unpack txt) 声明,但无论如何,我不需要/不想遍历 Text 值。)
有没有办法强制 Alloy 将类型视为原子类型?我希望避免使用新类型来包装 Text,因为所有使用 AST 的代码都需要处理它,这反而违背了使用泛型来避免样板的目的。
【问题讨论】:
标签: haskell