Questions about the array APIs

Chris Kuklewicz haskell at
Fri Nov 17 14:30:18 EST 2006

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
>> 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

More information about the Libraries mailing list