I was looking into io-streams and so on and had trouble with a simple
repeated parsing problem.
The results of the following bench are
$ time ./iostreamsbench pipes1
0
real 0m0.007s
$ time ./iostreamsbench pipes2
5568690515
real 0m1.277s
$ time ./iostreamsbench pipes3
12500002500000
real 0m0.887s
$ time ./iostreamsbench streams
12500002500000
real 0m1.138s
Of these the last two are correct (note the pleasing time comparison fwiw).
Why does pipes1 make no progress unless, as in pipes2, I delete the
first byte? What is my mistake?
{-#LANGUAGE OverloadedStrings#-}
import System.IO.Streams (InputStream, OutputStream)
import qualified System.IO.Streams as Streams
import qualified System.IO.Streams.Attoparsec as Streams
import Data.Attoparsec.Char8
import Data.Attoparsec
import Pipes
import qualified Pipes.Prelude as P
import qualified Pipes.ByteString as PB
import qualified Pipes.Attoparsec as P
import Control.Monad
import Control.Applicative
import Data.Monoid
import System.Environment (getArgs)
import qualified System.IO as IO
-- > writeFile "numbers.txt" $ unlines (map show [1..5000000])
numbers = "txt/numbers.txt"
entry :: Parser Int
entry = decimal <* char '\n'
main = do a <- getArgs
IO.withFile numbers IO.ReadMode $ \h ->
case a of ["streams"] -> streams h
["pipes1"] -> pipes1 h
["pipes2"] -> pipes2 h
["pipes3"] -> pipes3 h
_ -> putStrLn "args: streams pipes1
pipes2 pipes3"
streams h = do inp <- Streams.handleToInputStream h
nums <- Streams.parserToInputStream mentry inp
Streams.fold (+) 0 nums >>= print
where mentry :: Parser (Maybe Int)
mentry = fmap Just entry <|> return Nothing
pipes1 h = do let pipe = P.parsed entry (PB.fromHandle h) >> return ()
P.fold (+) 0 id pipe >>= print
pipes2 h = do let pipe = P.parsed entry (PB.fromHandle h >-> PB.drop 1)
>> return ()
P.fold (+) 0 id pipe >>= print
pipes3 h = do let pipe = repeatedly entry (PB.fromHandle h) >> return
()
P.fold (+) 0 id pipe >>= print
repeatedly :: Monad m -- not quite right
=> Parser a -> Producer PB.ByteString m r
-> Producer a m (Either r (Producer PB.ByteString m r))
repeatedly parser p = do
x <- lift (next p)
case x of Left e -> return (Left e)
Right (t,p1) -> go (yield t >>) (parse parser t) p1
where
go diffP iResult p0 = case iResult of
Fail _ c m -> return (Right (diffP p0)) -- note nothing is
returning Left ...
Done t a -> do yield a
go (yield t >>) (parse parser t) p0
Partial k -> do x <- lift $ next p0
case x of
Left e -> go diffP (k mempty) (return e)
Right (t, p1) -> go (diffP . (yield t >>)) (k
t) p1
--
You received this message because you are subscribed to the Google Groups
"Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].