+{-# OPTIONS_GHC -fno-bang-patterns #-}
+
-----------------------------------------------------------------------------
-- |
-- Module : Data.Array.Base
-- the type looks like constrained over 's', which runST doesn't
-- like. In fact all MArray (STUArray s) instances are polymorphic
-- wrt. 's', but runST can't know that.
-
--- I would like to write a rule for listUArrayST (or listArray or
+--
+-- More precisely, we'd like to write this:
+-- listUArray :: (forall s. MArray (STUArray s) e (ST s), Ix i)
+-- => (i,i) -> [e] -> UArray i e
+-- listUArray lu = runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
+-- {-# RULES listArray = listUArray
+-- Then we could call listUArray at any type 'e' that had a suitable
+-- MArray instance. But sadly we can't, because we don't have quantified
+-- constraints. Hence the mass of rules below.
+
+-- I would like also to write a rule for listUArrayST (or listArray or
-- whatever) applied to unpackCString#. Unfortunately unpackCString#
-- calls seem to be floated out, then floated back into the middle
-- of listUArrayST, so I was not able to do this.
+#ifdef __GLASGOW_HASKELL__
+type ListUArray e = forall i . Ix i => (i,i) -> [e] -> UArray i e
+
{-# RULES
-"listArray/UArray/Bool" listArray = \lu (es :: [Bool]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Char" listArray = \lu (es :: [Char]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Int" listArray = \lu (es :: [Int]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Word" listArray = \lu (es :: [Word]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Ptr" listArray = \lu (es :: [Ptr a]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/FunPtr" listArray = \lu (es :: [FunPtr a]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Float" listArray = \lu (es :: [Float]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Double" listArray = \lu (es :: [Double]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/StablePtr" listArray = \lu (es :: [StablePtr a]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Int8" listArray = \lu (es :: [Int8]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Int16" listArray = \lu (es :: [Int16]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Int32" listArray = \lu (es :: [Int32]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Int64" listArray = \lu (es :: [Int64]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Word8" listArray = \lu (es :: [Word8]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Word16" listArray = \lu (es :: [Word16]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Word32" listArray = \lu (es :: [Word32]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
-"listArray/UArray/Word64" listArray = \lu (es :: [Word64]) ->
- runST (listUArrayST lu es >>= unsafeFreezeSTUArray)
+"listArray/UArray/Bool" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Bool
+"listArray/UArray/Char" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Char
+"listArray/UArray/Int" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Int
+"listArray/UArray/Word" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Word
+"listArray/UArray/Ptr" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray (Ptr a)
+"listArray/UArray/FunPtr" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray (FunPtr a)
+"listArray/UArray/Float" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Float
+"listArray/UArray/Double" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Double
+"listArray/UArray/StablePtr" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray (StablePtr a)
+"listArray/UArray/Int8" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Int8
+"listArray/UArray/Int16" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Int16
+"listArray/UArray/Int32" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Int32
+"listArray/UArray/Int64" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Int64
+"listArray/UArray/Word8" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Word8
+"listArray/UArray/Word16" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Word16
+"listArray/UArray/Word32" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Word32
+"listArray/UArray/Word64" listArray
+ = (\lu es -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray)) :: ListUArray Word64
#-}
+#endif
{-# INLINE (!) #-}
-- | Returns the element of an immutable array at the specified index.
{-# INLINE unsafeAccumArray #-}
unsafeAccumArray f init lu ies = runST (unsafeAccumArrayUArray f init lu ies)
-instance Ix ix => Eq (UArray ix Bool) where
+instance (Ix ix, Eq e, IArray UArray e) => Eq (UArray ix e) where
(==) = eqUArray
-instance Ix ix => Eq (UArray ix Char) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Int) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Word) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix (Ptr a)) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix (FunPtr a)) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Float) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Double) where
- (==) = eqUArray
-
-#ifdef __GLASGOW_HASKELL__
-instance Ix ix => Eq (UArray ix (StablePtr a)) where
- (==) = eqUArray
-#endif
-
-instance Ix ix => Eq (UArray ix Int8) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Int16) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Int32) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Int64) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Word8) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Word16) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Word32) where
- (==) = eqUArray
-
-instance Ix ix => Eq (UArray ix Word64) where
- (==) = eqUArray
-
-instance Ix ix => Ord (UArray ix Bool) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Char) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Int) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Word) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix (Ptr a)) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix (FunPtr a)) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Float) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Double) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Int8) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Int16) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Int32) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Int64) where
+instance (Ix ix, Ord e, IArray UArray e) => Ord (UArray ix e) where
compare = cmpUArray
-instance Ix ix => Ord (UArray ix Word8) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Word16) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Word32) where
- compare = cmpUArray
-
-instance Ix ix => Ord (UArray ix Word64) where
- compare = cmpUArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Bool) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Char) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Int) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Word) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Float) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Double) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Int8) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Int16) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Int32) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Int64) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Word8) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Word16) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Word32) where
- showsPrec = showsIArray
-
-instance (Ix ix, Show ix) => Show (UArray ix Word64) where
+instance (Ix ix, Show ix, Show e, IArray UArray e) => Show (UArray ix e) where
showsPrec = showsIArray
-----------------------------------------------------------------------------
Note that because the array is possibly not copied, any subsequent
modifications made to the mutable version of the array may be
- shared with the immutable version. It is safe to use, therefore, if
- the immutable version is never referenced again.
+ shared with the immutable version. It is only safe to use,
+ therefore, if the immutable array is never referenced again in this
+ thread, and there is no possibility that it can be also referenced
+ in another thread. If you use an unsafeThaw/write/unsafeFreeze
+ sequence in a multi-threaded setting, then you must ensure that
+ this sequence is atomic with respect to other threads, or a garbage
+ collector crash may result (because the write may be writing to a
+ frozen array).
The non-copying implementation is supported between certain pairs
of array types only; one constraint is that the array types must
have identical representations. In GHC, The following pairs of
array types have a non-copying O(1) implementation of
- 'unsafeFreeze'. Because the optimised versions are enabled by
+ 'unsafeThaw'. Because the optimised versions are enabled by
specialisations, you will need to compile with optimisation (-O) to
get them.