array 0.5.2.0 → 0.5.8.0
raw patch · 16 files changed
Files
- Data/Array.hs +0/−2
- Data/Array/Base.hs +310/−79
- Data/Array/IArray.hs +12/−0
- Data/Array/IO.hs +1/−1
- Data/Array/IO/Internals.hs +18/−25
- Data/Array/IO/Safe.hs +1/−1
- Data/Array/MArray.hs +12/−1
- Data/Array/MArray/Safe.hs +9/−0
- Data/Array/ST.hs +1/−10
- Data/Array/ST/Safe.hs +1/−1
- Data/Array/Storable.hs +1/−0
- Data/Array/Storable/Internals.hs +13/−1
- LICENSE +1/−0
- Setup.hs +1/−0
- array.cabal +6/−7
- changelog.md +56/−0
Data/Array.hs view
@@ -54,8 +54,6 @@ ) where import Data.Ix-import Data.Typeable ()- import GHC.Arr -- Most of the hard work is done here {- $intro
Data/Array/Base.hs view
@@ -1,6 +1,16 @@-{-# LANGUAGE BangPatterns, CPP, RankNTypes, MagicHash, UnboxedTuples, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, DeriveDataTypeable, UnliftedFFITypes #-}-{-# LANGUAGE RoleAnnotations #-}-{-# OPTIONS_HADDOCK hide #-}+{-# LANGUAGE+ BangPatterns+ , CPP+ , RankNTypes+ , MagicHash+ , UnboxedTuples+ , MultiParamTypeClasses+ , FlexibleInstances+ , FlexibleContexts+ , UnliftedFFITypes+ , RoleAnnotations+ #-}+{-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- -- |@@ -15,31 +25,45 @@ -- Basis for IArray and MArray. Not intended for external consumption; -- use IArray or MArray instead. --+-- = WARNING+--+-- This module is considered __internal__.+--+-- The Package Versioning Policy __does not apply__.+--+-- The contents of this module may change __in any way whatsoever__+-- and __without any warning__ between minor versions of this package.+--+-- Authors importing this module are expected to track development+-- closely. ----------------------------------------------------------------------------- module Data.Array.Base where import Control.Monad.ST.Lazy ( strictToLazyST ) import qualified Control.Monad.ST.Lazy as Lazy (ST)-import Data.Ix ( Ix, range, index, rangeSize )+import Data.Ix ( Ix, range, index, inRange, rangeSize ) import Foreign.C.Types import Foreign.StablePtr import Data.Char-import GHC.Arr ( STArray )+import GHC.Arr ( STArray, unsafeIndex ) import qualified GHC.Arr as Arr import qualified GHC.Arr as ArrST import GHC.ST ( ST(..), runST ) import GHC.Base ( IO(..), divInt# ) import GHC.Exts import GHC.Ptr ( nullPtr, nullFunPtr )+import GHC.Show ( appPrec ) import GHC.Stable ( StablePtr(..) )+import GHC.Read ( expectP, parens, Read(..) ) import GHC.Int ( Int8(..), Int16(..), Int32(..), Int64(..) ) import GHC.Word ( Word8(..), Word16(..), Word32(..), Word64(..) ) import GHC.IO ( stToIO ) import GHC.IOArray ( IOArray(..), newIOArray, unsafeReadIOArray, unsafeWriteIOArray )-import Data.Typeable+import Text.Read.Lex ( Lexeme(Ident) )+import Text.ParserCombinators.ReadPrec ( prec, ReadPrec, step ) #include "MachDeps.h" @@ -170,35 +194,26 @@ let n = safeRangeSize (l,u) in unsafeArray (l,u) (zip [0 .. n - 1] es) -{-# INLINE listArrayST #-}+{-# INLINE genArray #-}+-- | Constructs an immutable array using a generator function.+--+-- @since 0.5.6.0+genArray :: (IArray a e, Ix i) => (i,i) -> (i -> e) -> a i e+genArray (l,u) f = listArray (l,u) $ map f $ range (l,u)++{-# INLINE listArrayST #-} -- See Note [Inlining and fusion] listArrayST :: Ix i => (i,i) -> [e] -> ST s (STArray s i e)-listArrayST (l,u) es = do- marr <- newArray_ (l,u)- let n = safeRangeSize (l,u)- let fillFromList i xs | i == n = return ()- | otherwise = case xs of- [] -> return ()- y:ys -> unsafeWrite marr i y >> fillFromList (i+1) ys- fillFromList 0 es- return marr+listArrayST = newListArray {-# RULES "listArray/Array" listArray = \lu es -> runST (listArrayST lu es >>= ArrST.unsafeFreezeSTArray) #-} -{-# INLINE listUArrayST #-}+{-# INLINE listUArrayST #-} -- See Note [Inlining and fusion] listUArrayST :: (MArray (STUArray s) e (ST s), Ix i) => (i,i) -> [e] -> ST s (STUArray s i e)-listUArrayST (l,u) es = do- marr <- newArray_ (l,u)- let n = safeRangeSize (l,u)- let fillFromList i xs | i == n = return ()- | otherwise = case xs of- [] -> return ()- y:ys -> unsafeWrite marr i y >> fillFromList (i+1) ys- fillFromList 0 es- return marr+listUArrayST = newListArray -- I don't know how to write a single rule for listUArrayST, because -- the type looks like constrained over 's', which runST doesn't@@ -259,11 +274,23 @@ #-} {-# INLINE (!) #-}--- | Returns the element of an immutable array at the specified index.+-- | Returns the element of an immutable array at the specified index,+-- or throws an exception if the index is out of bounds. (!) :: (IArray a e, Ix i) => a i e -> i -> e (!) arr i = case bounds arr of (l,u) -> unsafeAt arr $ safeIndex (l,u) (numElements arr) i +{-# INLINE (!?) #-}+-- | Returns 'Just' the element of an immutable array at the specified index,+-- or 'Nothing' if the index is out of bounds.+--+-- @since 0.5.6.0+(!?) :: (IArray a e, Ix i) => a i e -> i -> Maybe e+(!?) arr i = let b = bounds arr in+ if inRange b i+ then Just $ unsafeAt arr $ unsafeIndex b i+ else Nothing+ {-# INLINE indices #-} -- | Returns a list of all the valid indices in an array. indices :: (IArray a e, Ix i) => a i e -> [i]@@ -359,6 +386,94 @@ ixmap (l,u) f arr = array (l,u) [(i, arr ! f i) | i <- range (l,u)] +-- | Lazy right-associative fold.+--+-- @since 0.5.8.0+foldrArray :: (IArray a e, Ix i) => (e -> b -> b) -> b -> a i e -> b+foldrArray f z = \a ->+ let !n = numElements a+ go i | i >= n = z+ | otherwise = f (unsafeAt a i) (go (i+1))+ in go 0+{-# INLINE foldrArray #-}++-- | Strict accumulating left-associative fold.+--+-- @since 0.5.8.0+foldlArray' :: (IArray a e, Ix i) => (b -> e -> b) -> b -> a i e -> b+foldlArray' f z0 = \a ->+ let !n = numElements a+ go !z i | i >= n = z+ | otherwise = go (f z (unsafeAt a i)) (i+1)+ in go z0 0+{-# INLINE foldlArray' #-}++-- | Lazy left-associative fold.+--+-- @since 0.5.8.0+foldlArray :: (IArray a e, Ix i) => (b -> e -> b) -> b -> a i e -> b+foldlArray f z = \a ->+ let !n = numElements a+ go i | i < 0 = z+ | otherwise = f (go (i-1)) (unsafeAt a i)+ in go (n-1)+{-# INLINE foldlArray #-}++-- | Strict accumulating right-associative fold.+--+-- @since 0.5.8.0+foldrArray' :: (IArray a e, Ix i) => (e -> b -> b) -> b -> a i e -> b+foldrArray' f z0 = \a ->+ let !n = numElements a+ go i !z | i < 0 = z+ | otherwise = go (i-1) (f (unsafeAt a i) z)+ in go (n-1) z0+{-# INLINE foldrArray' #-}++-- | Map elements to applicative actions, sequence them left-to-right, and+-- discard the results.+--+-- @since 0.5.8.0+traverseArray_+ :: (IArray a e, Ix i, Applicative f) => (e -> f b) -> a i e -> f ()+traverseArray_ f = foldrArray (\x z -> f x *> z) (pure ())+{-# INLINE traverseArray_ #-}++-- | @forArray_@ is 'traverseArray_' with its arguments flipped.+--+-- @since 0.5.8.0+forArray_ :: (IArray a e, Ix i, Applicative f) => a i e -> (e -> f b) -> f ()+forArray_ = flip traverseArray_+{-# INLINE forArray_ #-}++-- | Strict accumulating left-associative monadic fold.+--+-- @since 0.5.8.0+foldlArrayM'+ :: (IArray a e, Ix i, Monad m) => (b -> e -> m b) -> b -> a i e -> m b+foldlArrayM' f z0 = \a ->+ let !n = numElements a+ go !z i | i >= n = pure z+ | otherwise = do+ z' <- f z (unsafeAt a i)+ go z' (i+1)+ in go z0 0+{-# INLINE foldlArrayM' #-}++-- | Strict accumulating right-associative monadic fold.+--+-- @since 0.5.8.0+foldrArrayM'+ :: (IArray a e, Ix i, Monad m) => (e -> b -> m b) -> b -> a i e -> m b+foldrArrayM' f z0 = \a ->+ let !n = numElements a+ go i !z | i < 0 = pure z+ | otherwise = do+ z' <- f (unsafeAt a i) z+ go (i-1) z'+ in go (n-1) z0+{-# INLINE foldrArrayM' #-}+ ----------------------------------------------------------------------------- -- Normal polymorphic arrays @@ -398,7 +513,6 @@ -- "Data.Array.Unboxed" instead of "Data.Array"). -- data UArray i e = UArray !i !i !Int ByteArray#- deriving Typeable -- There are class-based invariants on both parameters. See also #9220. type role UArray nominal nominal @@ -471,7 +585,7 @@ {-# RULES "cmpUArray/Int" cmpUArray = cmpIntUArray #-} -------------------------------------------------------------------------------- Showing IArrays+-- Showing and Reading IArrays {-# SPECIALISE showsIArray :: (IArray UArray e, Ix i, Show i, Show e) =>@@ -480,12 +594,24 @@ showsIArray :: (IArray a e, Ix i, Show i, Show e) => Int -> a i e -> ShowS showsIArray p a =- showParen (p > 9) $+ showParen (p > appPrec) $ showString "array " . shows (bounds a) . showChar ' ' . shows (assocs a) +{-# SPECIALISE+ readIArray :: (IArray UArray e, Ix i, Read i, Read e) =>+ ReadPrec (UArray i e)+ #-}++readIArray :: (IArray a e, Ix i, Read i, Read e) => ReadPrec (a i e)+readIArray = parens $ prec appPrec $+ do expectP (Ident "array")+ theBounds <- step readPrec+ vals <- step readPrec+ return (array theBounds vals)+ ----------------------------------------------------------------------------- -- Flat unboxed arrays: instances @@ -638,7 +764,7 @@ -- bogus StablePtr value for initialising a UArray of StablePtr. nullStablePtr :: StablePtr a-nullStablePtr = StablePtr (unsafeCoerce# 0#)+nullStablePtr = StablePtr (unsafeCoerce# nullAddr#) instance IArray UArray Int8 where {-# INLINE bounds #-}@@ -777,6 +903,9 @@ instance (Ix ix, Show ix, Show e, IArray UArray e) => Show (UArray ix e) where showsPrec = showsIArray +instance (Ix ix, Read ix, Read e, IArray UArray e) => Read (UArray ix e) where+ readPrec = readIArray+ ----------------------------------------------------------------------------- -- Mutable arrays @@ -796,24 +925,27 @@ in which the mutable array will be manipulated. -} class (Monad m) => MArray a e m where-- -- | Returns the bounds of the array+ -- | Returns the bounds of the array (lowest,highest). getBounds :: Ix i => a i e -> m (i,i)- -- | Returns the number of elements in the array+ -- | Returns the number of elements in the array. getNumElements :: Ix i => a i e -> m Int -- | Builds a new array, with every element initialised to the supplied- -- value.+ -- value. The first and second element of the tuple specifies the lowest+ -- and highest index, respectively. newArray :: Ix i => (i,i) -> e -> m (a i e) -- | Builds a new array, with every element initialised to an -- undefined value. In a monadic context in which operations must -- be deterministic (e.g. the ST monad), the array elements are -- initialised to a fixed but undefined value, such as zero.+ -- The first and second element of the tuple specifies the lowest+ -- and highest index, respectively. newArray_ :: Ix i => (i,i) -> m (a i e) -- | Builds a new array, with every element initialised to an undefined- -- value.+ -- value. The first and second element of the tuple specifies the lowest+ -- and highest index, respectively. unsafeNewArray_ :: Ix i => (i,i) -> m (a i e) unsafeRead :: Ix i => a i e -> Int -> m e@@ -850,6 +982,8 @@ -- default initialisation with undefined values if we *do* know the -- initial value and it is constant for all elements. + {-# MINIMAL getBounds, getNumElements, (newArray | unsafeNewArray_), unsafeRead, unsafeWrite #-}+ instance MArray IOArray e IO where {-# INLINE getBounds #-} getBounds (IOArray marr) = stToIO $ getBounds marr@@ -859,21 +993,41 @@ unsafeRead = unsafeReadIOArray unsafeWrite = unsafeWriteIOArray -{-# INLINE newListArray #-}+{-# INLINE newListArray #-} -- See Note [Inlining and fusion] -- | Constructs a mutable array from a list of initial elements. -- The list gives the elements of the array in ascending order--- beginning with the lowest index.+-- beginning with the lowest index. The first and second element+-- of the tuple specifies the lowest and highest index, respectively. newListArray :: (MArray a e m, Ix i) => (i,i) -> [e] -> m (a i e) newListArray (l,u) es = do marr <- newArray_ (l,u) let n = safeRangeSize (l,u)- let fillFromList i xs | i == n = return ()- | otherwise = case xs of- [] -> return ()- y:ys -> unsafeWrite marr i y >> fillFromList (i+1) ys- fillFromList 0 es+ f x k i+ | i == n = return ()+ | otherwise = unsafeWrite marr i x >> k (i+1)+ foldr f (\ !_i -> return ()) es 0+ -- The bang above is important for GHC for unbox the Int. return marr +{-# INLINE newGenArray #-}+-- | Constructs a mutable array using a generator function.+-- It invokes the generator function in ascending order of the indices.+--+-- @since 0.5.6.0+newGenArray :: (MArray a e m, Ix i) => (i,i) -> (i -> m e) -> m (a i e)+newGenArray bnds f = do+ let n = safeRangeSize bnds+ marr <- unsafeNewArray_ bnds+ let g ix k i+ | i == n = return ()+ | otherwise = do+ x <- f ix+ unsafeWrite marr i x+ k (i+1)+ foldr g (\ !_i -> return ()) (range bnds) 0+ -- The bang above is important for GHC for unbox the Int.+ return marr+ {-# INLINE readArray #-} -- | Read an element from a mutable array readArray :: (MArray a e m, Ix i) => a i e -> i -> m e@@ -890,6 +1044,31 @@ n <- getNumElements marr unsafeWrite marr (safeIndex (l,u) n i) e +{-# INLINE modifyArray #-}+-- | Modify an element in a mutable array+--+-- @since 0.5.6.0+modifyArray :: (MArray a e m, Ix i) => a i e -> i -> (e -> e) -> m ()+modifyArray marr i f = do+ (l,u) <- getBounds marr+ n <- getNumElements marr+ let idx = safeIndex (l,u) n i+ x <- unsafeRead marr idx+ unsafeWrite marr idx (f x)++{-# INLINE modifyArray' #-}+-- | Modify an element in a mutable array. Strict in the written element.+--+-- @since 0.5.6.0+modifyArray' :: (MArray a e m, Ix i) => a i e -> i -> (e -> e) -> m ()+modifyArray' marr i f = do+ (l,u) <- getBounds marr+ n <- getNumElements marr+ let idx = safeIndex (l,u) n i+ x <- unsafeRead marr idx+ let !x' = f x+ unsafeWrite marr idx x'+ {-# INLINE getElems #-} -- | Return a list of all the elements of a mutable array getElems :: (MArray a e m, Ix i) => a i e -> m [e]@@ -933,6 +1112,70 @@ | i' <- range (l',u')] return marr' +-- | Strict accumulating left-associative fold.+--+-- @since 0.5.8.0+foldlMArray' :: (MArray a e m, Ix i) => (b -> e -> b) -> b -> a i e -> m b+foldlMArray' f = foldlMArrayM' (\z x -> pure (f z x))+{-# INLINE foldlMArray' #-}++-- | Strict accumulating right-associative fold.+--+-- @since 0.5.8.0+foldrMArray' :: (MArray a e m, Ix i) => (e -> b -> b) -> b -> a i e -> m b+foldrMArray' f = foldrMArrayM' (\x z -> pure (f x z))+{-# INLINE foldrMArray' #-}++-- | Strict accumulating left-associative monadic fold.+--+-- @since 0.5.8.0+foldlMArrayM' :: (MArray a e m, Ix i) => (b -> e -> m b) -> b -> a i e -> m b+foldlMArrayM' f z0 = \a -> do+ !n <- getNumElements a+ let go !z i | i >= n = pure z+ | otherwise = do+ x <- unsafeRead a i+ z' <- f z x+ go z' (i+1)+ go z0 0+{-# INLINE foldlMArrayM' #-}++-- | Strict accumulating right-associative monadic fold.+--+-- @since 0.5.8.0+foldrMArrayM' :: (MArray a e m, Ix i) => (e -> b -> m b) -> b -> a i e -> m b+foldrMArrayM' f z0 = \a -> do+ !n <- getNumElements a+ let go i !z | i < 0 = pure z+ | otherwise = do+ x <- unsafeRead a i+ z' <- f x z+ go (i-1) z'+ go (n-1) z0+{-# INLINE foldrMArrayM' #-}++-- | Map elements to monadic actions, sequence them left-to-right, and discard+-- the results.+--+-- @since 0.5.8.0+mapMArrayM_ :: (MArray a e m, Ix i) => (e -> m b) -> a i e -> m ()+mapMArrayM_ f = \a -> do+ !n <- getNumElements a+ let go i | i >= n = pure ()+ | otherwise = do+ x <- unsafeRead a i+ _ <- f x+ go (i+1)+ go 0+{-# INLINE mapMArrayM_ #-}++-- | @forMArrayM_@ is 'mapMArrayM_' with its arguments flipped.+--+-- @since 0.5.8.0+forMArrayM_ :: (MArray a e m, Ix i) => a i e -> (e -> m b) -> m ()+forMArrayM_ = flip mapMArrayM_+{-# INLINE forMArrayM_ #-}+ ----------------------------------------------------------------------------- -- Polymorphic non-strict mutable arrays (ST monad) @@ -979,7 +1222,6 @@ -- don\'t use 'STUArray' if you require the non-strictness that -- 'STArray' provides. data STUArray s i e = STUArray !i !i !Int (MutableByteArray# s)- deriving Typeable -- The "ST" parameter must be nominal for the safety of the ST trick. -- The other parameters have class constraints. See also #9220. type role STUArray nominal nominal nominal@@ -1323,8 +1565,15 @@ bOOL_SCALE, wORD_SCALE, dOUBLE_SCALE, fLOAT_SCALE :: Int# -> Int# bOOL_SCALE n# =- -- + 7 to handle case where n is not divisible by 8- (n# +# 7#) `uncheckedIShiftRA#` 3#+ -- Round the number of bits up to the next whole-word-aligned number+ -- of bytes to avoid ghc#23132; the addition can signed-overflow but+ -- that's OK because it will not unsigned-overflow and the logical+ -- right-shift brings us back in-bounds+#if SIZEOF_HSWORD == 4+ ((n# +# 31#) `uncheckedIShiftRL#` 5#) `uncheckedIShiftL#` 2#+#elif SIZEOF_HSWORD == 8+ ((n# +# 63#) `uncheckedIShiftRL#` 6#) `uncheckedIShiftL#` 3#+#endif wORD_SCALE n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSWORD dOUBLE_SCALE n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSDOUBLE fLOAT_SCALE n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSFLOAT@@ -1370,18 +1619,14 @@ -- use the safe array creation function here. return (listArray (l,u) es) -#if __GLASGOW_HASKELL__ >= 711 freezeSTUArray :: STUArray s i e -> ST s (UArray i e)-#else-freezeSTUArray :: Ix i => STUArray s i e -> ST s (UArray i e)-#endif freezeSTUArray (STUArray l u n marr#) = ST $ \s1# ->- case sizeofMutableByteArray# marr# of { n# ->- case newByteArray# n# s1# of { (# s2#, marr'# #) ->+ case getSizeofMutableByteArray# marr# s1# of { (# s2#, n# #) ->+ case newByteArray# n# s2# of { (# s3#, marr'# #) -> case memcpy_freeze marr'# marr# (fromIntegral (I# n#)) of { IO m ->- case unsafeCoerce# m s2# of { (# s3#, _ #) ->- case unsafeFreezeByteArray# marr'# s3# of { (# s4#, arr# #) ->- (# s4#, UArray l u n arr# #) }}}}}+ case unsafeCoerce# m s3# of { (# s4#, _ #) ->+ case unsafeFreezeByteArray# marr'# s4# of { (# s5#, arr# #) ->+ (# s5#, UArray l u n arr# #) }}}}} foreign import ccall unsafe "memcpy" memcpy_freeze :: MutableByteArray# s -> MutableByteArray# s -> CSize@@ -1449,11 +1694,7 @@ | i <- [0 .. n - 1]] return marr -#if __GLASGOW_HASKELL__ >= 711 thawSTUArray :: UArray i e -> ST s (STUArray s i e)-#else-thawSTUArray :: Ix i => UArray i e -> ST s (STUArray s i e)-#endif thawSTUArray (UArray l u n arr#) = ST $ \s1# -> case sizeofByteArray# arr# of { n# -> case newByteArray# n# s1# of { (# s2#, marr# #) ->@@ -1513,11 +1754,7 @@ unsafeThaw = thaw {-# INLINE unsafeThawSTUArray #-}-#if __GLASGOW_HASKELL__ >= 711 unsafeThawSTUArray :: UArray i e -> ST s (STUArray s i e)-#else-unsafeThawSTUArray :: Ix i => UArray i e -> ST s (STUArray s i e)-#endif unsafeThawSTUArray (UArray l u n marr#) = return (STUArray l u n (unsafeCoerce# marr#)) @@ -1527,11 +1764,7 @@ #-} {-# INLINE unsafeThawIOArray #-}-#if __GLASGOW_HASKELL__ >= 711 unsafeThawIOArray :: Arr.Array ix e -> IO (IOArray ix e)-#else-unsafeThawIOArray :: Ix ix => Arr.Array ix e -> IO (IOArray ix e)-#endif unsafeThawIOArray arr = stToIO $ do marr <- ArrST.unsafeThawSTArray arr return (IOArray marr)@@ -1540,11 +1773,7 @@ "unsafeThaw/IOArray" unsafeThaw = unsafeThawIOArray #-} -#if __GLASGOW_HASKELL__ >= 711 thawIOArray :: Arr.Array ix e -> IO (IOArray ix e)-#else-thawIOArray :: Ix ix => Arr.Array ix e -> IO (IOArray ix e)-#endif thawIOArray arr = stToIO $ do marr <- ArrST.thawSTArray arr return (IOArray marr)@@ -1553,11 +1782,7 @@ "thaw/IOArray" thaw = thawIOArray #-} -#if __GLASGOW_HASKELL__ >= 711 freezeIOArray :: IOArray ix e -> IO (Arr.Array ix e)-#else-freezeIOArray :: Ix ix => IOArray ix e -> IO (Arr.Array ix e)-#endif freezeIOArray (IOArray marr) = stToIO (ArrST.freezeSTArray marr) {-# RULES@@ -1565,11 +1790,7 @@ #-} {-# INLINE unsafeFreezeIOArray #-}-#if __GLASGOW_HASKELL__ >= 711 unsafeFreezeIOArray :: IOArray ix e -> IO (Arr.Array ix e)-#else-unsafeFreezeIOArray :: Ix ix => IOArray ix e -> IO (Arr.Array ix e)-#endif unsafeFreezeIOArray (IOArray marr) = stToIO (ArrST.unsafeFreezeSTArray marr) {-# RULES@@ -1582,3 +1803,13 @@ castSTUArray :: STUArray s ix a -> ST s (STUArray s ix b) castSTUArray (STUArray l u n marr#) = return (STUArray l u n marr#)++--------------------------------------------------------------------------------++-- Note [Inlining and fusion]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~+-- Many functions in this module are marked INLINE because they consume their+-- input with `foldr`. By inlining them, it is possible that the `foldr` will+-- meet a `build` from the call site, and beneficial fusion will take place.+-- That is, they become "good consumers". See array issue #8 for data showing+-- the perf improvement that comes with fusion.
Data/Array/IArray.hs view
@@ -29,13 +29,25 @@ array, -- :: (IArray a e, Ix i) => (i,i) -> [(i, e)] -> a i e listArray, -- :: (IArray a e, Ix i) => (i,i) -> [e] -> a i e accumArray, -- :: (IArray a e, Ix i) => (e -> e' -> e) -> e -> (i,i) -> [(i, e')] -> a i e+ genArray, -- :: (IArray a e, Ix i) => (i,i) -> (i -> e) -> a i e -- * Accessing arrays (!), -- :: (IArray a e, Ix i) => a i e -> i -> e+ (!?), -- :: (IArray a e, Ix i) => a i e -> i -> Maybe e bounds, -- :: (HasBounds a, Ix i) => a i e -> (i,i) indices, -- :: (HasBounds a, Ix i) => a i e -> [i] elems, -- :: (IArray a e, Ix i) => a i e -> [e] assocs, -- :: (IArray a e, Ix i) => a i e -> [(i, e)]++ -- * Array folds+ foldrArray,+ foldlArray',+ foldlArray,+ foldrArray',+ traverseArray_,+ forArray_,+ foldlArrayM',+ foldrArrayM', -- * Incremental array updates (//), -- :: (IArray a e, Ix i) => a i e -> [(i, e)] -> a i e
Data/Array/IO.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE MagicHash, UnliftedFFITypes #-}+{-# LANGUAGE MagicHash, Trustworthy, UnliftedFFITypes #-} ----------------------------------------------------------------------------- -- |
Data/Array/IO/Internals.hs view
@@ -1,8 +1,10 @@-{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses,- CPP #-}-{-# LANGUAGE RoleAnnotations #-}+{-# LANGUAGE+ FlexibleInstances+ , MultiParamTypeClasses+ , RoleAnnotations+ #-} -{-# OPTIONS_HADDOCK hide #-}+{-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Array.IO.Internal@@ -15,6 +17,18 @@ -- -- Mutable boxed and unboxed arrays in the IO monad. --+-- = WARNING+--+-- This module is considered __internal__.+--+-- The Package Versioning Policy __does not apply__.+--+-- The contents of this module may change __in any way whatsoever__+-- and __without any warning__ between minor versions of this package.+--+-- Authors importing this module are expected to track development+-- closely.+-- ----------------------------------------------------------------------------- module Data.Array.IO.Internals (@@ -27,15 +41,11 @@ import Data.Int import Data.Word-import Data.Typeable import Control.Monad.ST ( RealWorld, stToIO ) import Foreign.Ptr ( Ptr, FunPtr ) import Foreign.StablePtr ( StablePtr ) -#if __GLASGOW_HASKELL__ < 711-import Data.Ix-#endif import Data.Array.Base import GHC.IOArray (IOArray(..))@@ -52,7 +62,6 @@ -- are supported: see "Data.Array.MArray" for a list of instances. -- newtype IOUArray i e = IOUArray (STUArray RealWorld i e)- deriving Typeable -- Both parameters have class-based invariants. See also #9220. type role IOUArray nominal nominal @@ -374,11 +383,7 @@ return (IOUArray marr') {-# INLINE unsafeThawIOUArray #-}-#if __GLASGOW_HASKELL__ >= 711 unsafeThawIOUArray :: UArray ix e -> IO (IOUArray ix e)-#else-unsafeThawIOUArray :: Ix ix => UArray ix e -> IO (IOUArray ix e)-#endif unsafeThawIOUArray arr = stToIO $ do marr <- unsafeThawSTUArray arr return (IOUArray marr)@@ -387,11 +392,7 @@ "unsafeThaw/IOUArray" unsafeThaw = unsafeThawIOUArray #-} -#if __GLASGOW_HASKELL__ >= 711 thawIOUArray :: UArray ix e -> IO (IOUArray ix e)-#else-thawIOUArray :: Ix ix => UArray ix e -> IO (IOUArray ix e)-#endif thawIOUArray arr = stToIO $ do marr <- thawSTUArray arr return (IOUArray marr)@@ -401,22 +402,14 @@ #-} {-# INLINE unsafeFreezeIOUArray #-}-#if __GLASGOW_HASKELL__ >= 711 unsafeFreezeIOUArray :: IOUArray ix e -> IO (UArray ix e)-#else-unsafeFreezeIOUArray :: Ix ix => IOUArray ix e -> IO (UArray ix e)-#endif unsafeFreezeIOUArray (IOUArray marr) = stToIO (unsafeFreezeSTUArray marr) {-# RULES "unsafeFreeze/IOUArray" unsafeFreeze = unsafeFreezeIOUArray #-} -#if __GLASGOW_HASKELL__ >= 711 freezeIOUArray :: IOUArray ix e -> IO (UArray ix e)-#else-freezeIOUArray :: Ix ix => IOUArray ix e -> IO (UArray ix e)-#endif freezeIOUArray (IOUArray marr) = stToIO (freezeSTUArray marr) {-# RULES
Data/Array/IO/Safe.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- |
Data/Array/MArray.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE CPP, Trustworthy #-} ----------------------------------------------------------------------------- -- |@@ -27,10 +27,21 @@ newArray, -- :: (MArray a e m, Ix i) => (i,i) -> e -> m (a i e) newArray_, -- :: (MArray a e m, Ix i) => (i,i) -> m (a i e) newListArray, -- :: (MArray a e m, Ix i) => (i,i) -> [e] -> m (a i e)+ newGenArray, -- :: (MArray a e m, Ix i) => (i,i) -> (i -> m e) -> m (a i e) -- * Reading and writing mutable arrays readArray, -- :: (MArray a e m, Ix i) => a i e -> i -> m e writeArray, -- :: (MArray a e m, Ix i) => a i e -> i -> e -> m ()+ modifyArray,+ modifyArray',++ -- * Array folds+ foldlMArray',+ foldrMArray',+ mapMArrayM_,+ forMArrayM_,+ foldlMArrayM',+ foldrMArrayM', -- * Derived arrays mapArray, -- :: (MArray a e' m, MArray a e m, Ix i) => (e' -> e) -> a i e' -> m (a i e)
Data/Array/MArray/Safe.hs view
@@ -29,10 +29,19 @@ newArray, -- :: (MArray a e m, Ix i) => (i,i) -> e -> m (a i e) newArray_, -- :: (MArray a e m, Ix i) => (i,i) -> m (a i e) newListArray, -- :: (MArray a e m, Ix i) => (i,i) -> [e] -> m (a i e)+ newGenArray, -- :: (MArray a e m, Ix i) => (i,i) -> (i -> m e) -> m (a i e) -- * Reading and writing mutable arrays readArray, -- :: (MArray a e m, Ix i) => a i e -> i -> m e writeArray, -- :: (MArray a e m, Ix i) => a i e -> i -> e -> m ()++ -- * Array folds+ foldlMArray',+ foldrMArray',+ mapMArrayM_,+ forMArrayM_,+ foldlMArrayM',+ foldrMArrayM', -- * Derived arrays mapArray, -- :: (MArray a e' m, MArray a e m, Ix i) => (e' -> e) -> a i e' -> m (a i e)
Data/Array/ST.hs view
@@ -1,5 +1,4 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RankNTypes, Trustworthy #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Array.ST@@ -38,11 +37,7 @@ -- the array before returning it - it uses 'unsafeFreeze' internally, but -- this wrapper is a safe interface to that function. ---#if __GLASGOW_HASKELL__ >= 711 runSTArray :: (forall s . ST s (STArray s i e)) -> Array i e-#else-runSTArray :: Ix i => (forall s . ST s (STArray s i e)) -> Array i e-#endif runSTArray st = runST (st >>= unsafeFreezeSTArray) -- | A safe way to create and work with an unboxed mutable array before@@ -51,11 +46,7 @@ -- 'unsafeFreeze' internally, but this wrapper is a safe interface to -- that function. ---#if __GLASGOW_HASKELL__ >= 711 runSTUArray :: (forall s . ST s (STUArray s i e)) -> UArray i e-#else-runSTUArray :: Ix i => (forall s . ST s (STUArray s i e)) -> UArray i e-#endif runSTUArray st = runST (st >>= unsafeFreezeSTUArray)
Data/Array/ST/Safe.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE Safe #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Array.ST.Safe
Data/Array/Storable.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Trustworthy #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Array.Storable
Data/Array/Storable/Internals.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, RoleAnnotations #-}-{-# OPTIONS_HADDOCK hide #-}+{-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Array.Storable.Internals@@ -13,6 +13,18 @@ -- Actual implementation of "Data.Array.Storable". -- -- @since 0.4.0.0+--+-- = WARNING+--+-- This module is considered __internal__.+--+-- The Package Versioning Policy __does not apply__.+--+-- The contents of this module may change __in any way whatsoever__+-- and __without any warning__ between minor versions of this package.+--+-- Authors importing this module are expected to track development+-- closely. ----------------------------------------------------------------------------- module Data.Array.Storable.Internals (
LICENSE view
@@ -81,3 +81,4 @@ be a definition of the Haskell 98 Foreign Function Interface. -----------------------------------------------------------------------------+
Setup.hs view
@@ -4,3 +4,4 @@ main :: IO () main = defaultMain+
array.cabal view
@@ -1,15 +1,15 @@+cabal-version: >= 1.10 name: array-version: 0.5.2.0+version: 0.5.8.0+ -- NOTE: Don't forget to update ./changelog.md license: BSD3 license-file: LICENSE maintainer: libraries@haskell.org-bug-reports: http://ghc.haskell.org/trac/ghc/newticket?component=libraries%20%28other%29&keywords=array+bug-reports: https://gitlab.haskell.org/ghc/packages/array/issues synopsis: Mutable and immutable arrays category: Data Structures build-type: Simple-cabal-version: >=1.10-tested-with: GHC==8.2.1, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4 description: In addition to providing the "Data.Array" module <http://www.haskell.org/onlinereport/haskell2010/haskellch14.html as specified in the Haskell 2010 Language Report>,@@ -21,14 +21,13 @@ source-repository head type: git- location: http://git.haskell.org/packages/array.git+ location: http://gitlab.haskell.org/ghc/packages/array.git library default-language: Haskell2010 other-extensions: BangPatterns, CPP,- DeriveDataTypeable, FlexibleContexts, FlexibleInstances, MagicHash,@@ -37,7 +36,7 @@ Trustworthy, UnboxedTuples, UnliftedFFITypes- build-depends: base >= 4.7 && < 4.11+ build-depends: base >= 4.9 && < 4.21 ghc-options: -Wall exposed-modules: Data.Array
changelog.md view
@@ -1,5 +1,61 @@ # Changelog for [`array` package](http://hackage.haskell.org/package/array) +## 0.5.8.0 *Aug 2024*++### Added++ * Folds for arrays: `foldrArray`, `foldlArray'`, `foldlArray`, `foldrArray'`,+ `traverseArray_`, `forArray_`, `foldlArrayM'`, `foldrArrayM'`.+ * Folds for mutable arrays: `foldlMArray'`, `foldrMArray'`, `mapMArrayM_`,+ `forMArrayM_`, `foldlMArrayM'`, `foldrMArrayM'`.++### Fixed++ * Fix a build error that the package can't be buildable before `base-4.14`.++## 0.5.7.0 *April 2024*++### Changed++ * `MArray` now has a `MINIMAL` pragma+ * Optimisation of `newListArray` and `newGenArray`++## 0.5.6.0 *July 2023*++### Changed++ * `listArray` and `newListArray` are now good consumers of the input list+ * Bump base bound to `<4.20`++### Added++ * Add the `genArray` and `newGenArray` function+ * Add `Data.Array.MArray.modifyArray` and `Data.Array.MArray.modifyArray'`+ These are also exposed from `Data.Array.IO`, `Data.Array.ST`, and+ `Data.Array.Storable`.+ * Add `Data.Array.IArray.(!?)`++### Fixed++ * Array docs regarding constructing arrays+ * Update note [Inlining and fusion]+ * Unboxed Bool arrays no longer cause spurious alarms+ when used with `-fcheck-prim-bounds`+ * Replace Haddock hide pragma with not-home to make the Haddocks more readable++## 0.5.5.0 *February 2022*++ * Compatibility with GHC's new JavaScript backend.++## 0.5.4.0 *July 2019*++ * Add a `Read` instance for `UArray`++## 0.5.3.0 *Oct 2018*++ * Bundled with GHC 8.6.2+ * Drop support for GHC versions prior to GHC 8.0+ ## 0.5.2.0 *Jul 2017* * Bundled with GHC 8.2.1