fuuman
fuuman

Reputation: 461

Haskell - writing a little parser

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

Answers (1)

Sibi
Sibi

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

Related Questions