{-# OPTIONS_GHC -fno-warn-tabs #-} -- | This module provides some arguably evil functions -- for turning your nice io-streams into lazy lists. module System.IO.Streams.Lazy where import Prelude hiding (read) import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BL import System.IO.Streams (InputStream, OutputStream, read) import System.IO.Streams.Concurrent (makeChanPipe) import System.IO.Unsafe (unsafeInterleaveIO) -- | Convert an input stream into a lazy list. toLazyList :: InputStream a -> IO [a] toLazyList is = unsafeInterleaveIO $ do ma <- read is case ma of Nothing -> return [] Just a -> do as <- toLazyList is return (a : as) -- | Create an output stream and a lazy list that contains the values -- that you feed into that output stream. Make sure you evaluate the list -- in a separate thread to the one you write to the stream in. lazyListOutput :: IO (OutputStream a, [a]) lazyListOutput = do (is, os) <- makeChanPipe as <- toLazyList is return (os, as) -- | Convert an input stream of strict `ByteString`s to a lazy `ByteString`. toLazyByteString :: InputStream BS.ByteString -> IO BL.ByteString toLazyByteString is = BL.fromChunks <$> toLazyList is -- | Create a lazy `ByteString` by feeding an `OutputStream` strict -- `ByteString`s lazyByteStringOutput :: IO (OutputStream BS.ByteString, BL.ByteString) lazyByteStringOutput = do (os, ll) <- lazyListOutput return (os, BL.fromChunks ll)