Very interesting - thanks!
"Gregory Collins" <[email protected]> wrote in message
news:[email protected]...
My enumerator style may not be the best (I'm long-winded), but
personally when the stream types are the same on input and output I
often skip the Enumeratee stuff and just write an Enumerator wrapper.
To address your complaint here:
PS Implementations which involve "EB.take count" seem to me
unsatisfactory;
one surely oughtn't need to have a large buffer to solve this problem
I'd write a helping combinator:
module Main where
import Control.Monad (when)
import Control.Monad.Trans
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Lazy.Char8 as L
import Data.Enumerator
import qualified Data.Enumerator.List as EL
import System.IO
takeUpTo :: Monad m =>
Int
-> Iteratee ByteString m (Stream ByteString, Int)
takeUpTo n' = continue k
where
n = toEnum n'
k EOF = yield (EOF,0) EOF
k (Chunks xs) = if taken == 0
then takeUpTo n'
else yield (stream, taken) rest
where
s = L.fromChunks xs
(a,b) = L.splitAt n s
taken = fromEnum $ L.length a
stream = Chunks $ L.toChunks a
rest = Chunks $ L.toChunks b
The code to run a side effect every N bytes is then pretty short (and
should be efficient):
sideEffectEveryNBytes :: Monad m =>
Int -- ^ run the side effect every N bytes
-> m () -- ^ side effect
-> Step ByteString m a
-> Iteratee ByteString m a
sideEffectEveryNBytes n act = flip checkContinue1 n $ \loop i k -> do
(str, taken) <- takeUpTo i
when (taken == i) $ lift act
(lift $ runIteratee $ k str) >>= loop (nextI $ i - taken)
where
nextI 0 = n
nextI i = i
Here's your particular example:
example :: IO [ByteString]
example = run_ $ enumList 1 [ "the quick brown "
, "fox "
, "jumped "
, "over "
, "the lazy dog" ] $$ it
where
it = do
xs <- sideEffectEveryNBytes 10 (putStr "." >> hFlush stdout) $$
EL.consume
lift $ putStrLn ""
return xs
Running it:
*Main> example
....
["the quick ","brown ","fox ","jumped ","ove","r ","the lazy"," dog"]
G
--
Gregory Collins <[email protected]>
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe