我在Haskell中使用Parsec
模块来解析文件。这些文件的一个组成部分是颜色。我已经为这样的颜色创建了一个类型:
data Color = Yellow | Red | Blue | Green deriving (Show)
我最初尝试解析颜色的方法如下:
symbol :: String -> Parsec String () String
symbol s = spaces >> string s
colorP :: Parsec String () Color
colorP =
liftM mkColor $ symbol "Yellow" <|> symbol "Red" <|> symbol "Blue" <|> symbol "Green"
where
mkColor :: String -> Color
mkColor "Yellow" = Yellow
mkColor "Red" = Red
mkColor "Blue" = Blue
mkColor "Green" = Green
我创建了symbol
解析器,它基本上占用了尽可能多的空格,然后吃掉了给定的字符串s
。但是,这似乎不起作用。我使用以下调用测试此代码:
parse colorP "" " Red"
这给了我以下错误:
unexpected "R"
expecting space or "Yellow"
但是,我在Hoogle上寻找与<|>
运营商合作的文档,并在那里找到了以下内容:
这个组合器实现了选择。解析器p&lt; |&gt;首先应用p。如果成功,则返回p的值。如果p在没有消耗任何输入的情况下失败,则尝试解析器q。
所以,我认为上面例子的问题是解析器p
(在这种情况下是symbol "Yellow"
)已经消耗了一些输入,即空白!所以,我像这样重构了colorP
:
colorP =
liftM mkColor $ spaces >> (string "Yellow" <|> string "Red" <|> string "Blue" <|> string "Green")
where
-- mkColor same as before
给出了我想要的结果。
现在,我想知道是否没有像我编写的symbol
解析器那样的解析器,但是如果失败则会放回输入。或者是colorP
的第二个实现是Haskell-ish最多的那个?
答案 0 :(得分:2)