2013-02-05 6 views
1

고정 길이 필드를 attoparsec로 구문 분석해야하지만 현재 컴파일러와 어려움을 겪고 있습니다.고정 길이 텍스트를 attoparsec으로 구문 분석

> {-# LANGUAGE OverloadedStrings #-} 
> import Control.Applicative 
> import Data.Text as T 
> import Data.Attoparsec.Combinator 
> import Data.Attoparsec.Text hiding (take) 
> import Data.Char 
> import Prelude hiding (take) 
> 
> type City = Text 
> type Ready = Bool 
> data CityReady = CR City Ready deriving Show 
> 
> input = T.unlines ["#London    1", 
>     "#Seoul    0", 
>     "#Tokyo    0", 
>     "#New York   1"] 
> 
> parseCityReady = many $ CR <$> cityParser <*> readyParser <* endOfLine 
> 
> cityParser = char '#' *> 
>    takeTill isSpace <* 
>    skipWhile isHorizontalSpace 
> 
> 
> readyParser = char '1' *> pure True <|> char '0' *> pure False 
> 
> main = 
> case parseOnly parseCityReady input of 
>  Left err -> print err 
>  Right xs -> mapM_ print xs 
> 

이 모두 훌륭하지만 그것은 단지 공백없이 도시를 반환 : 임은 여전히 ​​초보자, 아래의 코드는 내가 가지고있는 가장 가까운 솔루션입니다.

CR "London" True 
CR "Seoul" False 
CR "Tokyo" False 

나는 도시 텍스트 문자열을 20 자 걸릴 실용적를 사용하여 시도

> cityParser = char '#' *> 
>    take 20 

심지어 do syntax

> cityParser = do char '#' 
>     city <- take 20 
>     return city 

하지만 두 가지 접근 방식은이 오류와 함께 컴파일에 실패 :

Couldn't match expected type `attoparsec-0.10.4.0:Data.Attoparsec.Internal.Types.Parser 
           Text b0' 
      with actual type `Text -> Text' 
In the return type of a call of `take' 
Probable cause: `take' is applied to too few arguments 
In the second argument of `(*>)', namely `take 20' 
In the expression: char '#' *> take 20 

take의 유형이 Int -> Text -> Text 일 때 ghc가 Text -> Text을 요청하게하는 원인은 무엇입니까?

어떻게 응용 프로그램과 구문 모두에서 해결할 수 있습니까?

+2

당신은 attoparsec''내 보낸 take''의 버전을 숨기고처럼 수입을 변경 입니다. 대신'Text' 모듈에서 내 보낸'take' 함수를 사용하고 있습니다. 이것은 원하는 것이 아닙니다. – sabauma

+0

@sabauma 참으로 DataText에'hiding'을 배치해야합니다. 감사! – georgina

+1

@sabauma : 정답이면 게시해야합니다. – sclv

답변

3

따라서 문제는 여러 버전의 take 기능을 숨기고 있다는 것입니다. 특히 takeText 모듈의 take 함수보다 이 아닌 attoparsec에서 숨기고 있습니다. 당신이해야한다 모든 그렇게

> import Control.Applicative 
> import Data.Attoparsec.Combinator 
> import Data.Attoparsec.Text 
> import Data.Char 
> import Data.Text as T hiding (take) 
> import Prelude hiding (take)