2017-02-02 5 views

ответ

1

Вы используете старую версию pipes-attoparsec, соответствующую старой версии pipes. В последних версиях что-то вроде первого примера будет написано без трубы. Мы использовали бы функцию parsed, которая просто применяет парсер до тех пор, пока не сработает, потоковая передача хороших анализов по мере их поступления.

{-# LANGUAGE OverloadedStrings #-} 
import Pipes 
import qualified Pipes.Prelude as P 
import Pipes.Attoparsec 
import Data.Attoparsec.Text 
import Data.Text (Text) 

data Name = Name Text deriving (Show) 

hello :: Parser Name 
hello = fmap Name $ "Hello " *> takeWhile1 (/='.') <* "." 

helloparses :: Monad m => Producer Text m r -> Producer Name m (Either (ParsingError, Producer Text m r) r) 
helloparses = parsed hello 

process txt = do 
    e <- runEffect $ helloparses txt >-> P.print 
    case e of 
    Left (err,rest) -> print err >> runEffect (rest >-> P.print) 
    Right()  -> return() 

input1, input2 :: Monad m => Producer Text m() 
input1 = each 
    [ "Hello Kate." 
    , "Hello Mary.Hello Jef" 
    , "f." 
    , "Hel" 
    , "lo Tom." 
    ] 
input2 = input1 >> yield "garbage" 

Тогда мы видим

-- >>> process input1 
-- Name "Kate" 
-- Name "Mary" 
-- Name "Jeff" 
-- Name "Tom" 

-- >>> process input2 
-- Name "Kate" 
-- Name "Mary" 
-- Name "Jeff" 
-- Name "Tom" 
-- ParsingError {peContexts = [], peMessage = "string"} 
-- "garbage" 

Другой принцип действия pipes-attoparsec определяется только parse. Это преобразует парсер attoparsec в синтаксический анализатор StateT для анализа исходного сегмента производителя, который соответствует синтаксическому анализатору. Вы можете прочитать о них здесь http://www.haskellforall.com/2014/02/pipes-parse-30-lens-based-parsing.html

+0

Спасибо, что нашли время, отвечая на мой вопрос. Похоже, что трубы-аттопарсец в последнее время сильно изменились. Учебник, на который я ссылался, абсолютно бесполезен и даже отвлекает. – user2812201

Смежные вопросы