[project @ 2005-02-02 14:54:18 by ross]
[ghc-base.git] / Data / Array / Base.hs
index 03d604c..6864362 100644 (file)
@@ -56,7 +56,8 @@ import Data.Typeable
 -----------------------------------------------------------------------------
 -- Class of immutable arrays
 
--- | Class of array types with bounds
+-- | Class of array types with immutable bounds
+-- (even if the array elements are mutable).
 class HasBounds a where
     -- | Extracts the bounds of an array
     bounds :: Ix i => a i e -> (i,i)
@@ -118,10 +119,13 @@ the array respectively.  For example, a one-origin vector of length 10
 has bounds (1,10), and a one-origin 10 by 10 matrix has bounds
 ((1,1),(10,10)).
 
-An association is a pair of the form @(i,x)@, which defines the value
-of the array at index @i@ to be @x@.  The array is undefined if any
-index in the list is out of bounds.  If any two associations in the
-list have the same index, the value at that index is undefined.
+An association is a pair of the form @(i,x)@, which defines the value of
+the array at index @i@ to be @x@.  The array is undefined if any index
+in the list is out of bounds.  If any two associations in the list have
+the same index, the value at that index is implementation-dependent.
+(In GHC, the last value specified for that index is used.
+Other implementations will also do this for unboxed arrays, but Haskell
+98 requires that for 'Array' the value at such indices is bottom.)
 
 Because the indices must be checked for these errors, 'array' is
 strict in the bounds argument and in the indices of the association
@@ -290,11 +294,15 @@ accumArray f init (l,u) ies =
 {-|
 Takes an array and a list of pairs and returns an array identical to
 the left argument except that it has been updated by the associations
-in the right argument. (As with the array function, the indices in the
-association list must be unique for the updated elements to be
-defined.) For example, if m is a 1-origin, n by n matrix, then
-@m\/\/[((i,i), 0) | i \<- [1..n]]@ is the same matrix, except with the
-diagonal zeroed.
+in the right argument.  For example, if m is a 1-origin, n by n matrix,
+then @m\/\/[((i,i), 0) | i \<- [1..n]]@ is the same matrix, except with
+the diagonal zeroed.
+
+As with the 'array' function, if any two associations in the list have
+the same index, the value at that index is implementation-dependent.
+(In GHC, the last value specified for that index is used.
+Other implementations will also do this for unboxed arrays, but Haskell
+98 requires that for 'Array' the value at such indices is bottom.)
 
 For most array types, this operation is O(/n/) where /n/ is the size
 of the array.  However, the 'Data.Array.Diff.DiffArray' type provides
@@ -538,19 +546,22 @@ instance IArray UArray Int where
     {-# INLINE unsafeAccumArray #-}
     unsafeAccumArray f init lu ies = runST (unsafeAccumArrayUArray f init lu ies)
 
-#ifdef __GLASGOW_HASKELL__
 instance IArray UArray Word where
     {-# INLINE unsafeArray #-}
     unsafeArray lu ies = runST (unsafeArrayUArray lu ies 0)
+#ifdef __GLASGOW_HASKELL__
     {-# INLINE unsafeAt #-}
     unsafeAt (UArray _ _ arr#) (I# i#) = W# (indexWordArray# arr# i#)
+#endif
+#ifdef __HUGS__
+    unsafeAt = unsafeAtBArray
+#endif
     {-# INLINE unsafeReplace #-}
     unsafeReplace arr ies = runST (unsafeReplaceUArray arr ies)
     {-# INLINE unsafeAccum #-}
     unsafeAccum f arr ies = runST (unsafeAccumUArray f arr ies)
     {-# INLINE unsafeAccumArray #-}
     unsafeAccumArray f init lu ies = runST (unsafeAccumArrayUArray f init lu ies)
-#endif
 
 instance IArray UArray (Ptr a) where
     {-# INLINE unsafeArray #-}
@@ -790,10 +801,8 @@ instance Ix ix => Eq (UArray ix Char) where
 instance Ix ix => Eq (UArray ix Int) where
     (==) = eqUArray
 
-#ifdef __GLASGOW_HASKELL__
 instance Ix ix => Eq (UArray ix Word) where
     (==) = eqUArray
-#endif
 
 instance Ix ix => Eq (UArray ix (Ptr a)) where
     (==) = eqUArray
@@ -845,10 +854,8 @@ instance Ix ix => Ord (UArray ix Char) where
 instance Ix ix => Ord (UArray ix Int) where
     compare = cmpUArray
 
-#ifdef __GLASGOW_HASKELL__
 instance Ix ix => Ord (UArray ix Word) where
     compare = cmpUArray
-#endif
 
 instance Ix ix => Ord (UArray ix (Ptr a)) where
     compare = cmpUArray
@@ -895,10 +902,8 @@ instance (Ix ix, Show ix) => Show (UArray ix Char) where
 instance (Ix ix, Show ix) => Show (UArray ix Int) where
     showsPrec = showsIArray
 
-#ifdef __GLASGOW_HASKELL__
 instance (Ix ix, Show ix) => Show (UArray ix Word) where
     showsPrec = showsIArray
-#endif
 
 instance (Ix ix, Show ix) => Show (UArray ix Float) where
     showsPrec = showsIArray
@@ -960,6 +965,10 @@ class (HasBounds a, Monad m) => MArray a e m where
     unsafeRead  :: Ix i => a i e -> Int -> m e
     unsafeWrite :: Ix i => a i e -> Int -> e -> m ()
 
+    {-# INLINE newArray #-}
+       -- The INLINE is crucial, because until we know at least which monad    
+       -- we are in, the code below allocates like crazy.  So inline it,
+       -- in the hope that the context will know the monad.
     newArray (l,u) init = do
         marr <- newArray_ (l,u)
         sequence_ [unsafeWrite marr i init | i <- [0 .. rangeSize (l,u) - 1]]
@@ -1062,16 +1071,9 @@ instance MArray (STArray s) e (ST s) where
     {-# INLINE unsafeWrite #-}
     unsafeWrite = ArrST.unsafeWriteSTArray
 
------------------------------------------------------------------------------
--- Typeable instance for STArray
-
-sTArrayTc :: TyCon
-sTArrayTc = mkTyCon "STArray"
-
-instance (Typeable a, Typeable b, Typeable c) => Typeable (STArray a b c) where
-  typeOf a = mkAppTy sTArrayTc [typeOf ((undefined :: STArray a b c -> a) a),
-                               typeOf ((undefined :: STArray a b c -> b) a),
-                               typeOf ((undefined :: STArray a b c -> c) a)]
+#ifdef __HUGS__
+INSTANCE_TYPEABLE3(STArray,sTArrayTc,"STArray")
+#endif
 
 -----------------------------------------------------------------------------
 -- Flat unboxed mutable arrays (ST monad)
@@ -1444,6 +1446,11 @@ instance MArray (STUArray s) Int (ST s) where
     unsafeRead = unsafeReadMBArray
     unsafeWrite = unsafeWriteMBArray
 
+instance MArray (STUArray s) Word (ST s) where
+    newArray_ = newMBArray_
+    unsafeRead = unsafeReadMBArray
+    unsafeWrite = unsafeWriteMBArray
+
 instance MArray (STUArray s) (Ptr a) (ST s) where
     newArray_ = newMBArray_
     unsafeRead = unsafeReadMBArray