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
을 요청하게하는 원인은 무엇입니까?
어떻게 응용 프로그램과 구문 모두에서 해결할 수 있습니까?
당신은 attoparsec''내 보낸 take''의 버전을 숨기고처럼 수입을 변경 입니다. 대신'Text' 모듈에서 내 보낸'take' 함수를 사용하고 있습니다. 이것은 원하는 것이 아닙니다. – sabauma
@sabauma 참으로 DataText에'hiding'을 배치해야합니다. 감사! – georgina
@sabauma : 정답이면 게시해야합니다. – sclv