gpt4 book ai didi

parsing - 了解读取实例

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

我做了ReadShow我的数据实例,但不明白Read实例

data Tests = Zero
| One Int
| Two Int Double

instance Show Tests where
show Zero = "ZERO"
show (One i) = printf "ONE %i" i
show (Two i j) = printf "TWO %i %f" i j

instance Read Tests where
readsPrec _ str = [(mkTests str, "")]

mkTests :: String -> Tests
mkTests = check . words

check :: [String] -> Tests
check ["ZERO"] = Zero
check ["ONE", i] = One (read i)
check ["TWO", i, j] = Two (read i) (read j)
check _ = error "no parse"

main :: IO ()
main = do
print Zero
print $ One 10
print $ Two 1 3.14

let x = read "ZERO" :: Tests
print x
let y = read "ONE 2" :: Tests
print y
let z = read "TWO 2 5.5" :: Tests
print z

这是输出

ZERO         
ONE 10
TWO 1 3.14
ZERO
ONE 2
TWO 2 5.5

以下是问题:

  1. 推荐的实现方式是什么 Read实例?

    • Read 的最小完整定义类(class)是 readsPrec | readPrecreadPrec :: ReadPrec a描述写

    Proposed replacement for readsPrec using new-style parsers (GHC only).

    • 我应该使用 readPrec相反,如何?我在网上找不到任何我能理解的例子。
    • 什么是 new-style parsers ,是parsec吗? ?
  2. 第一个是什么Int readsPrec :: Int -> ReadS a 的参数,用于?

  3. 有没有办法以某种方式导出 Read来自Show

过去我可以使用 deriving (Show,Read)完成大部分工作。但这一次我想更上一层楼。

最佳答案

  1. 在我看来,实现 Read 的正确方法是派生它,否则,最好转向更复杂的解析器。无论如何,这是您所有问题的答案。
      readPrec 是 GHC 提供的一种基于简单解析器组合器的方法。如果您愿意牺牲 Read 实例的可移植性,您可以使用它,它使解析更容易。
    • 我在下面提供了一个如何使用 readPrec 的小示例
    • parsec 与 readPrec 不同,但是两者都类似于解析器组合器。 Parsec是一个更完整的解析器库。另一个解析器组合器库是 attoparsec其工作原理与秒差距非常相似。
    • parsec 和 attoparsec 不能与普通的 Read 类型类一起使用(至少不能直接使用),但它们提供的更大灵 active 使它们成为您需要更复杂解析的任何时候的好主意。
  2. Int readsPrec 的参数用于在解析时处理优先级。当您想要解析算术表达式时,这可能很重要。如果优先级高于当前运算符的优先级,您可以选择解析失败。
  3. 推导Read来自Show不幸的是这是不可能的。

这里有几个片段展示了我将如何实现 Read使用ReadPrec .

ReadPrec 示例:

instance Read Tests where
readPrec = choice [pZero, pOne, pTwo] where
pChar c = do
c' <- get
if c == c'
then return c
else pfail
pZero = traverse pChar "ZERO" *> pure Zero
pOne = One <$> (traverse pChar "ONE " *> readPrec)
pTwo = Two <$> (traverse pChar "TWO " *> readPrec) <*> readPrec

一般来说,实现 Read 不如更重量级的解析器直观。根据您想要解析的内容,我强烈建议您学习 parsec 或 attoparsec,因为当您想要解析更复杂的事物时,它们非常有用。

关于parsing - 了解读取实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44733857/

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