Questions about the array APIs

Chris Kuklewicz haskell at list.mightyreason.com
Fri Nov 17 05:51:07 EST 2006


Iavor Diatchki wrote:
> Hello,
> 
> On 11/15/06, Chris Kuklewicz <haskell at list.mightyreason.com> wrote:
>> Iavor Diatchki wrote:
>> > Hello,
>> > I have two questions about the array APIs in the libraries:
>>
>> > 1. Is there a way to write an immutable array to a handle without
>> > using any unsafe methods?
>>
>> In what format?  There is no canonical form for an IArray except for
>> Show/Read.
> I should have been more clear.  I was thinking of an array of bytes,
> and I was wondering if there is a function like 'hPutArray' from
> Data.IO.Array that works on immutable arrays (e.g, ordinary Haskell
> arrays, or unboxed immutable arrays of bytes).  Using 'hPutArray' is
> not good in this case because to turn an immutable array into a
> muttable one we have to copy it.

In general, the IArray interface supports many data layouts and semantics for
the instances.  The standard Haskell Array is lazy where each item in the array
can be a thunk; therefore there is no contiguous series of bytes in memory to
send to a handle.

There are IArray instances that do have such layouts in memory:

  Data.Array.Storable has such a layout and you can get the Ptr:

withStorableArray :: StorableArray i e -> (Ptr e -> IO a) -> IO a

which can be combined with System.IO's

hPutBuf :: Handle -> Ptr a -> Int -> IO ()

to define (using Foreign.Storable's sizeOf):

hPutStorableArray :: Handle -> StorableArray i e -> IO ()
hPutStorableArray h arr = withStorableArray arr (\ptr -> hPutBuf h (sizeOf arr))

Alternatively you can use Data.MArray's unsafeThaw (in GHC at least) to turn an
array of type UArray into an IOUArray WITHOUT MAKING A COPY and then use
Data.Array.IO's hPutArray:

hPutUArray :: Handle -> UArray i e -> IO ()
hPutUArray h u'arr = do iou'arr <- unsafeThaw u'arr
                        iou'arr'bytes <- castIOUArray iou'arr
                        hPutArray h iou'arr'bytes

where the castIOUArray is needed to change the element type to Word8.

I have not tested the above, so there are probably a few errors.

>> > 2. Why does the function 'getBounds' (of the 'MArray' class) return
>> > its result in a monad?
>>
>> It is so that mutable arrays which dynamically change their bounds can
>> be supported.
> 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.

Cheers,
  Chris


More information about the Libraries mailing list