2012-10-25 3 views
9

Parsec 파서 작성에 Applicative 스타일을 사용하는 방법을 이해하는 데 도움을 줄 수 있습니까?Parsec 및 Applicative 스타일

module Main where 
import Control.Applicative hiding (many) 
import Text.Parsec 
import Data.Functor.Identity 
data Cmd = A | B deriving (Show) 

main = do 
    line <- getContents 
    putStrLn . show $ parseCmd line 

parseCmd :: String -> Either ParseError String 
parseCmd input = parse cmdParse "(parser)" input 

cmdParse :: Parsec String() String 
cmdParse = do 
    slash <- char '/' 
    whatever <- many alphaNum 
    return (slash:whatever) 

cmdParse2 :: String -> Parsec String() String 
cmdParse2 = (:) <$> (char '/') <*> many alphaNum 

을하지만 난 컴파일 할 때, 나는 다음과 같은 얻을 :

/home/tomasherman/Desktop/funinthesun.hs:21:13: 
    Couldn't match expected type `Parsec String() String' 
       with actual type `[a0]' 
    Expected type: a0 -> [a0] -> Parsec String() String 
     Actual type: a0 -> [a0] -> [a0] 
    In the first argument of `(<$>)', namely `(:)' 
    In the first argument of `(<*>)', namely `(:) <$> (char '/')' 
Failed, modules loaded: none. 

아이디어는 내가 cmdParse2가 cmdParse가하는 같은 일을 할 것입니다,하지만 사용이 내가 가지고있는 코드입니다 applicative 물건 ... 내 접근 방식은 아마 완전히 잘못되었습니다, 난 haskell에 처음이에요

+0

귀하의 오류가있다'(++) <$> ...'하지'(:) <$>을 ... '. – huon

+0

죄송합니다, 고정 .. 나는 모두와 함께 노력했다 + + : 그리고 그것을 섞여있어 – Arg

+4

답변은 "음, 잘 선택, 잘 했어,하지만이 사소한 오류를 해결하기 때문에 잘 연구 질문 궁극 . " +1 – AndrewC

답변

4

귀하의 응용 용도에 문제가 있습니다. 부정확 한 서명이 있습니다. 보십시오 : 당신이 쓴 것처럼

cmdParse2 :: Parsec String() String 
+1

어리 석음, 감사합니다 – Arg

+0

그냥 빠른 질문입니다. 'many alphaNum'에서 텍스트를 가져올 수 있습니까? 그래서 내가 문자열 대신 텍스트를 사용하려면 수동으로 포장하지 않아도됩니까? – Arg

+0

@Arg 1. 예. 'cmdParse3 = cons <$> char '/'<*> (꾸러미 <$> 많은 alphaNum)'을 변환 할 필요가 있지만'cmdParse4 = pack <$> cmdParse2'가 더 좋을 것입니다 :'(pack <$> many alphaNum)'을 변환 할 수 있습니다. , 응용 프로그램에 따라 끝까지 끝내고'pack <$> myTopLevelParser'를 실행하는 것이 더 나을 수도 있습니다. (당신은'Text.Parsec.Text'에 관심이있어 소스 데이터를 변경할 수도 있습니다.) 2. 왜? 문자열을 한 번에 하나씩 만들어서 좋은 방법으로 결합합니다. 어쨌든'append'는 _O (n) _입니다. – AndrewC

4

당신의 접근 방식이 나에게 맞는 것 같아요, 문제는 cmdParse2에 잘못된 유형이 있다는 것입니다. cmdParse과 동일한 유형이어야합니다. 그건 그렇고, applicative 스타일 파서에서 char '/' 주변의 괄호를 생략 할 수 있습니다.

+0

멋지다, p 스 팁 덕분에 – Arg