Reputation: 461
I want to write a little parser for soccer scores.
For example the input "0:2"
should be parsed to Just (Score 0 2)
. If there is something like "3:3"
it should give me "Nothing"
. Everything else should be give me "Nothing"
, too.
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
The parser that I give the runParsec as an argument looks until now like this:
parseScore :: Parser Score
parseScore str1 = case str1 of
"x:y" && (x /= y) -> Right Score x y
Otherwise -> Left x
I know, that this code for parseScore is unable to work. Because I cannot pattern match with a String like "x:y". But how can I solve this problem?
runParsec parseScore "0:2"
should give me Just (Score 0 2)
I'm thankful for hints.
Thanks!
Upvotes: 1
Views: 359
Reputation: 48766
Just write a proper Parser
for your type and filter out the things you don't need:
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
Demo in ghci
:
λ> runParsec "0:2"
Just (Score 0 2)
λ> runParsec "3:3"
Nothing
λ> runParsec "3:4"
Nothing
What can I do, if I want to accept all scores, 1:0, 0:4 and so on? Everything, but no random input like "jirjgir" and no equal scores like "2:2" or "5:5"
Just change your filtering conditions:
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
Demo:
λ> runParsec "1:0"
Just (Score 1 0)
λ> runParsec "0:4"
Just (Score 0 4)
λ> runParsec "2:2"
Nothing
λ> runParsec "jiraf"
Nothing
Upvotes: 5