我正在使用Haskell中的Parsec
模塊解析文件。這些文件的組件之一是顏色。我創建了一個類型的顏色是這樣的:解析parsec之前的空白或-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爲與<|>
運營商進入的文件和在那裏我發現以下內容:
This combinator implements choice. The parser p <|> q first applies p. If it succeeds, the value of p is returned. If p fails without consuming any input, parser q is tried.
所以,我覺得上面的示例的問題是,解析器p
(在這種情況下symbol "Yellow"
)alrea dy確實消耗了一些輸入,即空白!所以,我重構了我的colorP
像這樣:
colorP =
liftM mkColor $ spaces >> (string "Yellow" <|> string "Red" <|> string "Blue" <|> string "Green")
where
-- mkColor same as before
它給出我想要的結果。
現在,我想知道是否沒有像我編寫的解析器symbol
這樣的解析器,但是在發生故障時會放回輸入。或者是第二次實現的是大多數Haskell-ish的第一個實現?