我想编写一个rename
函数,用作为单子中隐藏状态的符号表中的名称(整数)替换我的String
名称(代表分层标识符) 。AST
GUID
Renamer
我有一个AST a
通过名称类型参数化的类型。AST 叶子中的名称类型为Name a
:
data Name a = Name a
这使得使用 SYB 变压器轻松定位它们。
解析器是键入的(为简洁起见忽略错误的可能性):
parse :: String -> AST String
我希望输入rename
函数:
rename :: AST String -> Renamer (AST GUID)
是否可以使用 SYB 将所有Name String
' 转换为Name GUID
' 与转换器:
resolveName :: Name String -> Renamer (Name GUID)
以及所有其他值 from c String
toc GUID
通过转换他们的孩子,并使用相同的构造函数将它们粘贴回一起,尽管使用不同的类型参数?
该everywhereM
功能接近我想要的,但它只能转换c a -> m (c a)
而不能c a -> m (c b)
。
我的后备解决方案(除了手动编写样板)是从 中删除类型参数AST
,并定义Name
如下:
data Name = StrName String
| GuidName GUID
以便输入重命名:
rename :: AST -> Renamer AST
使其与everywhereM
. 但是,这会留下 an在重命名后AST
仍然可以持有's的可能性。我想使用类型系统来正式捕获重命名只能包含名称StrName
的事实。AST
GUID