gpt4 book ai didi

haskell - attoparsec 如何返回不同类型的值?

转载 作者:行者123 更新时间:2023-12-04 01:41:47 28 4
gpt4 key购买 nike

我被 attoparsec 困住了,我无法返回关于它是“嵌入式类型”的值。

我试图解析一个文件:

type
value
type
value
...

例如:

0 -- code for a string value
hello
70 -- code for an int value
10
0
world
20 -- code for a double value
5.20

我当前的数据类型是:

data KeyValue = forall a. (Typeable a, Show a, Eq a) => KeyValue (Int, a)
instance Eq KeyValue where -- as I need to test equality
KeyValue (code1, value1) == KeyValue (code2, value2) =
code1 == code2 && case cast value2 of
Just value2' -> value1 == value2
Nohing -> False

我的解析器看起来像:

parser :: Parser [KeyValue]
parser = many' (keyValue <* endOfLine)

keyValue :: Parser KeyValue
keyValue = do
key <- decimal <* endOfLine
value <- case key of
0 -> takeLine
20 -> double
70 -> decimal
_ -> takeLine
return $ KeyValue (key, value)

takeLine :: Parser Text
takeLine = takeTill isEndOfLine

但是 GHC 提示说:

Couldn't match type Double with Text
Expected type: Parser Text Text
Actual type: Parser Double
In the expression: double
In a case alternative: 20 -> double

我理解原因,但不知道如何解决这个问题!

目前,我使用 ExistantialQuantification pragma 和 Data.Typeable,但我不确定解决方案是否需要“如此复杂” 有那个问题吗?

最佳答案

创建一个总和类型并让您的解析器返回它,例如:

data SumType = Str String | Int Int | Double Double

keyvalue :: Parser SumType
keyvalue = ...

现在 keyvalue 可以以 return (Str "foo") 结束,以指示字符串已被解析或以 return (Int 23) 等表示一个 int 已经被解析。

例如像这样的东西:

keyValue = do
key <- decimal <* endOfLine
case key of
20 -> do d <- parseDouble; return (Double d)
70 -> do i <- parseInt; return (Int i)
...

关于haskell - attoparsec 如何返回不同类型的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31685685/

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