2014-07-19 3 views
1

축구 점수를위한 작은 파서를 쓰고 싶습니다.하스켈 - 작은 파서 작성

예를 들어 입력 "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이 코드가 작동 할 수 없음을

parseScore :: Parser Score 
parseScore str1 = case str1 of 
    "x:y" && (x /= y) -> Right Score x y 
    Otherwise   -> Left x 

나도 알아. 왜냐하면 나는 "x : y"와 같은 문자열과 패턴 매치를 할 수 없기 때문이다. 그러나이 문제를 어떻게 해결할 수 있습니까?

runParsec parseScore "0:2" 나에게 Just (Score 0 2)

내가 힌트를 감사 해요를 제공해야합니다.

감사합니다.

+2

'3 : 3'은 '점수 3 3'또는 '아무것도 없음'을 제공해야합니까? – Sibi

+0

아무 것도. "5 : 1"- 그냥 (점수 5 1)/"3 : 3"- 아무것도 아닙니다./"우후허에"- 아무것도. – fuuman

+1

'3 : 3'이 유효한 점수 일 때 왜 '아무것도'하지 않아야합니까? – Lee

답변

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 등을 받아들이고 싶습니까?

그냥 필터링 조건을 변경 : "5 5": 모든하지만 "jirjgir"없이 동일한 점수 같은 "2"와 같은 어떤 임의의 입력 또는

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 
+1

bikeshedding : 왜 단지'integer :: Parser Int; 정수 = 읽기 <$> many1 digit'. 로컬 정의를 전역 유형 서명으로 바꿉니다. – rampion

+0

@rampion 전 세계적인 정의라고 생각합니다. 형식 서명을 추가하지 않았습니다. 서명을 포함하도록 업데이트합니다. – Sibi

+0

나는'rd'의 로컬 정의를 의미했습니다 – rampion