
Iavor Diatchki wrote:
Hello,
I am aware of the unsafe methods to cast arrays. My question was if there was a function in the libraries to dump an immutable array of bytes to a handle, that is safe (it could, of course, be implemented behind the scene using unsafe primitives, however, this is implementation specific). My impression was that there isn't one, and I guess you are confirming this. I think it would be useful to have such a function in the libraries.
That is right. In GHC, the "array of bytes" is mutable: either a Ptr or a StorableArray. The UArray is implemented as an immutable "array of bytes" but you cannot get the Ptr to this without unsafeThaw. But since hPutUArray does not use the IOUArray to write to memory this is actually safe, and hGetUArray forgets the IOUArray so it is safe:
import System.IO import Data.Word import Data.Array.Unboxed import Data.Array.IO
hPutUArray :: Handle -> UArray Int Word8 -> IO () hPutUArray h u'arr = do iou'arr <- unsafeThaw u'arr let (a,b) = bounds u'arr hPutArray h iou'arr (b-a+1)
hGetUArray :: Handle -> (Int,Int) -> IO (UArray Int Word8) hGetUArray h bnds@(a,b) = do iou'arr <- newArray_ bnds let len = b-a+1 len' <- hGetArray h iou'arr len if len/=len' then fail $ "Not enough bytes from handle:" ++ show (len,len') else unsafeFreeze iou'arr
where this time I actually loaded up the code and made it compile. So you now have your IArray of bytes: the UArray instance.
There do not appear to be methods in the MArray class that allow arrays to change their bounds...
True: There are MArray instances that cannot change their size, therefore the MArray class does not specify those operations are available. It have merely been changed to accommodate them by making getBounds monadic.
See http://haskell.org/haskellwiki/Library/ArrayRef#Reimplemented_Arrays_library
for (possibly dynamically) resizable instances.
I was not aware of this, thanks for the reference. I need to look at it more closely, but didn't this decision remove an important point in the design space, namely mutable arrays of a fixed size? I would imagine these are quite important when you care about managing resources. I guess the monadic 'getBounds' still supports them but it looses some type information...
-Iavor