gpt4 book ai didi

parsing - Haskell:将读取函数提升到秒差距解析器

转载 作者:行者123 更新时间:2023-12-02 21:07:17 25 4
gpt4 key购买 nike

作为第四次练习的一部分 here我想使用 reads 类型函数,例如带有 parsec ParserreadHex

为此,我编写了一个函数:

liftReadsToParse :: Parser String -> (String -> [(a, String)]) -> Parser a
liftReadsToParse p f = p >>= \s -> if null (f s) then fail "No parse" else (return . fst . head ) (f s)

可以使用它,例如在 GHCI 中,如下所示:

*Main Numeric> parse (liftReadsToParse (many1 hexDigit) readHex) "" "a1"
Right 161

任何人都可以在以下方面对这种方法提出任何改进建议:

  • 术语(f s)是否会被内存,或者在null (f s)返回False的情况下被评估两次>?
  • 处理多个成功的解析,即当length (f s)大于1时,我不知道parsec如何处理这个问题。
  • 处理解析的剩余部分,即 (snd . head) (f s)

  • 最佳答案

    这是个好主意。一种更自然的方法可以使你的 ReadS 解析器更适合 Parsec 是在类型的开头省略 Parser String:

    liftReadS :: ReadS a -> String -> Parser a
    liftReadS reader = maybe (unexpected "no parse") (return . fst) .
    listToMaybe . filter (null . snd) . reader

    这种“组合器”风格是非常惯用的 Haskell - 一旦你习惯它,它使函数定义变得更容易阅读和理解。

    然后,在简单的情况下,您将像这样使用 liftReadS:

    > parse (many1 hexDigit >>= liftReadS readHex) "" "a1"

    (请注意,listToMaybe 位于 Data.Maybe 模块中。)

    在更复杂的情况下,liftReadS 很容易在任何内部使用秒差距 do block 。

    关于您的一些其他问题:

    1. 函数 reader 现在仅应用一次,因此无需“内存”任何内容。
    2. 在大多数情况下,忽略 ReadS 解析器中除第一个解析之外的所有解析是常见且可接受的做法,因此没问题。

    关于parsing - Haskell:将读取函数提升到秒差距解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3568767/

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