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].

Reply via email to