gpt4 book ai didi

haskell - finally 无标记解析和递归单子(monad) Action

转载 作者:行者123 更新时间:2023-12-02 03:34:58 24 4
gpt4 key购买 nike

我以 finally tagless 风格从磁盘反序列化数据结构。即

class SYM repl where
a :: repl
include :: FilePath -> repl

myParser :: SYM r => Parser r

我正在解析的语言包含指令。

我正在使用 attoparsec,它不是 monad 转换器,所以我不能简单地提供一个类型 Loader = FilePath -> IO (Maybe Text)

我可以使用以下 SYM 实例编写解释器,解析包含。

instance SYM r => SYM (Loader -> IO (Either String r)) where
include path loader =
maybe (Left "cannot load") (parseOnly myParser) <$> loader path

不幸的是,包含在包含文件中的内容没有得到解决。当然我可以解决它们两次以解决下一层。但如果我想为每个可能的级别都这样做,那会导致无限类型。

现在我预加载所有包含(在 HashMap 中)并绑定(bind)它们,所以我可以将 FilePath -> Maybe Text 传递给解析器并解析包含在那里,但这显然不是最优的。 (并且 include 不再是 SYM 的一部分。)

我的问题是,finally 无标签样式如何解决这个问题?

编辑:我在 lpaste 上发布了一个完整的示例:http://lpaste.net/105182

最佳答案

事后看来这很容易,但通常是这样。

单层解析简单如下。

instance SYM r => SYM (Loader -> IO (Either String r)) where
token t _ = return . Right $ token t
include path loader =
maybe (Left "cannot load") (parseOnly myParser) <$> loader path

即它将在(成功)加载的文件上运行 parseOnly myParser::Either String r

resolve-everything 只需要为 myParser 选择 SYM (Loader -> IO (Either String r)) 实例并添加 loader 参数:

    include path loader =
maybe (return $ Left "cannot load")
(either (return ∘ Left) ($ loader) . parseOnly myParser)
=<< loader path

关键的一步是它将额外的参数加载器提供给新的parseOnlyd SYM repl,从而选择正确的实例。

完整的片段在带注释的 lambda 粘贴中:http://lpaste.net/105182 .输入“include include token”进行测试

关于haskell - finally 无标记解析和递归单子(monad) Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24078311/

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