From 649199c02cbaa6499bd545852d937cdfff7e812f Mon Sep 17 00:00:00 2001 From: Joachim Breitner <mail@joachim-breitner.de> Date: Sun, 18 Jun 2023 08:53:29 +0000 Subject: [PATCH] Add genArray and newGenArray --- Data/Array/Base.hs | 15 +++++++++++++++ Data/Array/IArray.hs | 1 + Data/Array/MArray.hs | 1 + Data/Array/MArray/Safe.hs | 1 + changelog.md | 2 ++ 5 files changed, 20 insertions(+) diff --git a/Data/Array/Base.hs b/Data/Array/Base.hs index 2862125c..e892c4ec 100644 --- a/Data/Array/Base.hs +++ b/Data/Array/Base.hs @@ -195,6 +195,11 @@ listArray (l,u) es = let n = safeRangeSize (l,u) in unsafeArray (l,u) (zip [0 .. n - 1] es) +{-# INLINE genArray #-} +-- | Constructs an immutable array using a generator function. +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 = newListArray @@ -906,6 +911,16 @@ newListArray (l,u) es = do foldr f (const (return ())) es 0 return marr +{-# INLINE newGenArray #-} +-- | Constructs a mutable array using a generator function. +-- It invokes the generator function in ascending order of the indices. +newGenArray :: (MArray a e m, Ix i) => (i,i) -> (i -> m e) -> m (a i e) +newGenArray (l,u) f = do + marr <- newArray_ (l,u) + let n = safeRangeSize (l,u) + sequence_ [ f i >>= unsafeWrite marr (safeIndex (l,u) n i) | i <- range (l,u)] + return marr + {-# INLINE readArray #-} -- | Read an element from a mutable array readArray :: (MArray a e m, Ix i) => a i e -> i -> m e diff --git a/Data/Array/IArray.hs b/Data/Array/IArray.hs index d381d13a..5f58f7e4 100644 --- a/Data/Array/IArray.hs +++ b/Data/Array/IArray.hs @@ -29,6 +29,7 @@ module Data.Array.IArray ( 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 diff --git a/Data/Array/MArray.hs b/Data/Array/MArray.hs index 7a89f395..1f92d55b 100644 --- a/Data/Array/MArray.hs +++ b/Data/Array/MArray.hs @@ -27,6 +27,7 @@ module Data.Array.MArray ( 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 diff --git a/Data/Array/MArray/Safe.hs b/Data/Array/MArray/Safe.hs index fcbf768c..be7a62e8 100644 --- a/Data/Array/MArray/Safe.hs +++ b/Data/Array/MArray/Safe.hs @@ -29,6 +29,7 @@ module Data.Array.MArray.Safe ( 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 diff --git a/changelog.md b/changelog.md index d6f11e41..1e861c07 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,8 @@ ## NEXT *TBA* + * add the `genArray` and `newGenArray` function + * `listArray` and `newListArray` are now good consumers of the input list. * Unboxed Bool arrays no longer cause spurious alarms -- GitLab