From 0b6a11a5726507dbdbd843034d8364121406325a Mon Sep 17 00:00:00 2001
From: meooow <soumiksarkar.3120@gmail.com>
Date: Sun, 18 Jun 2023 08:00:16 +0000
Subject: [PATCH] Add Data.MArray.{modifyArray,modifyArray'}

---
 Data/Array/Base.hs   | 25 +++++++++++++++++++++++++
 Data/Array/MArray.hs |  2 ++
 changelog.md         |  4 ++++
 3 files changed, 31 insertions(+)

diff --git a/Data/Array/Base.hs b/Data/Array/Base.hs
index 0cea0717..2862125c 100644
--- a/Data/Array/Base.hs
+++ b/Data/Array/Base.hs
@@ -922,6 +922,31 @@ writeArray marr i e = do
   n <- getNumElements marr
   unsafeWrite marr (safeIndex (l,u) n i) e
 
+{-# INLINE modifyArray #-}
+-- | Modify an element in a mutable array
+--
+-- @since FIXME
+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 FIXME
+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]
diff --git a/Data/Array/MArray.hs b/Data/Array/MArray.hs
index 7f0f1054..7a89f395 100644
--- a/Data/Array/MArray.hs
+++ b/Data/Array/MArray.hs
@@ -31,6 +31,8 @@ module Data.Array.MArray (
     -- * 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',
 
     -- * Derived arrays
     mapArray,     -- :: (MArray a e' m, MArray a e m, Ix i) => (e' -> e) -> a i e' -> m (a i e)
diff --git a/changelog.md b/changelog.md
index fb51a091..d6f11e41 100644
--- a/changelog.md
+++ b/changelog.md
@@ -9,6 +9,10 @@
 
   * Add `Data.Array.IArray.(!?)`
 
+  * 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`.
+
 ## 0.5.5.0  *February 2022*
 
   * Compatibility with GHC's new JavaScript backend.
-- 
GitLab