
Peter Simons wrote:
Hence, mutable values that look like pure ones become unpredictable and are considered a major sin in Haskell land, please don't do it.
It feels patronizing to tell someone else what he should or shouldn't do. What can I say? Outside of Haskell land there are people who believe that software should, like, work, instead of falling apart whenever you feed it input data larger than a few kilobytes and to reach that objective those people are absolutely prepared to face the wild unpredictability of -- *gasp* -- pointers!
I didn't intend to patronize, I apologize for the harsh words. It's just that there's a difference between manipulating pointers peek :: Ptr Word8 -> IO Word8 -- :) poke :: Word8 -> Ptr Word8 -> IO () and breaking language semantics peek :: Ptr Word8 -> Word8 -- :( poke :: Word8 -> Ptr Word8 -> ()
As catBuf crucially depends on the mutability of the buffer, ByteStrings are not the right data structure to use in that case, that's all there is to it.
A ByteString is a pointer, a byte size, and a byte offset. As such, it is the perfect data structure for a program like catBuf.
Not quite. ByteStrings are intended to be a memory-efficient representation of Strings and the memory efficiency is implemented in Haskell with buffers and unsafePeformIO. But great care is taken to preserve language semantics in the exported API which means that ByteStrings have to be immutable. Note that the copy function is not for assuring immutability but for handling possible space leaks. Regards, apfelmus