
Peter Simons wrote:
This design, however, is obviously meant for data streams: the concept of seeking simply doesn't exist. So although you can run a BlockIO handler from any conceivable input source, you cannot fit any conceivable input/output model into BlockIO.
It seems to me a 'block' system _could_ abstract many IO types, its just that the block size would change and there would need to be a way of seeking. It seems to me seeking could be easily added to the design, one possibility would be to pass a block list to withBuffer: withBuffer :: [Int] -> (Buffer -> IO a) -> IO a This is quite flexible, because the 'return' value could be another list of blocks. If we rearrange the arguments we can get: withBuffer :: (Buffer -> IO a) -> [Int] -> IO a Then it should be possible to write: mfix (withBuffer m) Which would require each application of 'm' to return a list of blocks to process... One remaining limitation is that the block processing must be independant of the blocks location... however if we allow the possibility of passing a state as well, the block processing function can depend on location, this can be achived by using the class definition of IO and allowing monad transformers (like StateT) to be used: withBuffer :: MonadIO m => (Buffer -> m a) -> [Int] -> m a Regards, Keean.