我想为足球比分写一点解析器.
例如,"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
Run Code Online (Sandbox Code Playgroud)
我将runParsec作为参数提供的解析器直到现在看起来像这样:
parseScore :: Parser Score
parseScore str1 = case str1 of
"x:y" && (x /= y) -> Right Score x y
Otherwise -> Left x
Run Code Online (Sandbox Code Playgroud)
我知道,parseScore的这段代码无法正常工作.因为我无法模式匹配像"x:y"这样的字符串.但是我该如何解决这个问题呢?
runParsec parseScore "0:2" 应该给我 Just (Score 0 2)
我很感谢提示.
谢谢!
只需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
Run Code Online (Sandbox Code Playgroud)
演示ghci:
?> runParsec "0:2"
Just (Score 0 2)
?> runParsec "3:3"
Nothing
?> runParsec "3:4"
Nothing
Run Code Online (Sandbox Code Playgroud)
我能做什么,如果我想接受所有分数,1:0,0:4等等?一切,但没有随机输入像"jirjgir"和没有相同的分数,如"2:2"或"5:5"
只需更改过滤条件:
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
Run Code Online (Sandbox Code Playgroud)
演示:
?> runParsec "1:0"
Just (Score 1 0)
?> runParsec "0:4"
Just (Score 0 4)
?> runParsec "2:2"
Nothing
?> runParsec "jiraf"
Nothing
Run Code Online (Sandbox Code Playgroud)