gpt4 book ai didi

haskell - 是否可以使用 SYB 转换类型?

转载 作者:行者123 更新时间:2023-12-04 21:24:45 25 4
gpt4 key购买 nike

我想写一个rename替换功能String我的 AST 中的名称(代表分层标识符)与 GUID Renamer 中作为隐藏状态携带的符号表中的名称(整数)单子(monad)。

我有一个 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)

以及来自 c String 的所有其他值至 c GUID通过转换他们的 child ,并使用相同的构造函数将它们粘贴在一起,尽管使用不同的类型参数?
everywhereM功能接近我想要的,但它只能转换 c a -> m (c a)而不是 c a -> m (c b) .

我的后备解决方案(除了手动编写样板)是从 AST 中删除类型参数, 并定义 Name像这样:
data Name = StrName String
| GuidName GUID

以便输入重命名:
rename :: AST -> Renamer AST

使它与 everywhereM 一起工作.但是,这将留下 AST 的可能性。还能持有 StrName改名后的。我想使用类型系统来正式捕获重命名的 AST 的事实。只能持有 GUID名字。

最佳答案

一种解决方案(可能比您希望的效率低)是让您的 AST 成为 Functor 的实例。 , DataTypeable (GHC 7 可能会为您导出所有这些)然后执行以下操作:

import Data.Generics.Uniplate.Data(universeBi) -- from the uniplate package
import qualified Data.Map as Map

rename :: AST String -> Renamer (AST GUID)
rename x = do
let names = nub $ universeBi x :: [Name String]
guids <- mapM resolveName names
let mp = Map.fromList $ zip names guids
return $ fmap (mp Map.!) x

两点:
  • 我假设很容易消除 Name来自 resolveName 的位,但我怀疑它是。
  • 可以切换universeBi对于 SYB 中的等价物,但我发现理解 Uniplate 版本要容易得多。
  • 关于haskell - 是否可以使用 SYB 转换类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5434889/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com