Мне нужно разобрать поля фиксированной длины с помощью 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
Что заставляет ghc запрашивать Text -> Text
, когда take
имеет тип Int -> Text -> Text
?
Как мне решить это как в аппликативном, так и в do-синтаксисе?
take
, экспортированнуюattoparsec
. Вместо этого вы используете функциюtake
, экспортированную модулемText
, которая вам не нужна. - person sabauma   schedule 05.02.2013hiding
в Data.Text. Спасибо! - person georgina   schedule 05.02.2013