
Iavor Diatchki wrote:
Hello,
On 11/15/06, Chris Kuklewicz
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