我想为足球比分写一点解析器。
例如,输入"0:2"
应解析为Just (Score 0 2)
。如果有类似"3:3"
的内容,则应该给我"Nothing"
。其他一切也应该给我"Nothing"
。
data Score = Score Int Int
deriving (Eq,Show,Ord)
runParsec :: Parser a -> String -> Maybe a
runParsec parser input = case runP parser () "" input of
Left _ -> Nothing
Right a -> Just a
我将runParsec作为参数提供的解析器现在看起来像这样:
parseScore :: Parser Score
parseScore str1 = case str1 of
"x:y" && (x /= y) -> Right Score x y
Otherwise -> Left x
我知道,parseScore的这段代码无法正常工作。因为我无法模仿匹配像" x:y"这样的字符串。但是我该如何解决这个问题呢?
runParsec parseScore "0:2"
应该给我Just (Score 0 2)
我很感谢提示。
谢谢!
答案 0 :(得分:5)
只需为您的类型写一个合适的Parser
并过滤掉您不需要的内容:
import Control.Applicative ((<$>))
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Char
data Score = Score Int Int deriving (Show)
parseScore :: Parser Score
parseScore = do
a <- integer
char ':'
b <- integer
return $ Score a b
integer :: Parser Int
integer = read <$> many1 digit
runParsec :: String -> Maybe Score
runParsec input = case parse parseScore "" input of
Left e -> Nothing
Right e -> case e of
Score 0 2 -> Just e
_ -> Nothing
ghci
演示:
λ> runParsec "0:2"
Just (Score 0 2)
λ> runParsec "3:3"
Nothing
λ> runParsec "3:4"
Nothing
如果我想接受所有分数,1:0,0:4等,我该怎么办? 一切,但没有随机输入,如&#34; jirjgir&#34;没有相同的分数 喜欢&#34; 2:2&#34;或&#34; 5:5&#34;
只需更改过滤条件:
runParsec :: String -> Maybe Score
runParsec input = case parse parseScore "" input of
Left e -> Nothing
Right e -> case e of
Score x y -> if x == y
then Nothing
else Just e
演示:
λ> runParsec "1:0"
Just (Score 1 0)
λ> runParsec "0:4"
Just (Score 0 4)
λ> runParsec "2:2"
Nothing
λ> runParsec "jiraf"
Nothing