@@ -23,13 +23,15 @@ module Data.TypeRepMap.Internal where
24import Prelude hiding (lookup)
24import Prelude hiding (lookup)
26+import Control.Monad.ST (runST)
26import Control.Monad.Zip (mzip)
27import Control.Monad.Zip (mzip)
27import Data.Function (on)
28import Data.Function (on)
28import Data.IntMap.Strict (IntMap)
29import Data.IntMap.Strict (IntMap)
29import Data.Kind (Type)
30import Data.Kind (Type)
30import Data.List (intercalate, nubBy)
31import Data.List (intercalate, nubBy)
31import Data.Maybe (fromJust)
32import Data.Maybe (fromJust)
32−import Data.Primitive.Array (Array, indexArray, mapArray')
33+import Data.Primitive.Array (Array, freezeArray, indexArray, mapArray', readArray, sizeofArray,
34+ thawArray, writeArray)
33import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
35import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
34import Data.Semigroup (Semigroup (..))
36import Data.Semigroup (Semigroup (..))
35import GHC.Base (Any, Int (..), Int#, (*#), (+#), (<#))
37import GHC.Base (Any, Int (..), Int#, (*#), (+#), (<#))
@@ -162,6 +164,28 @@ delete :: forall a (f :: KindOf a -> Type) . Typeable a => TypeRepMap f -> TypeR
162delete = fromTriples . deleteByFst (typeFp @a) . toTriples
164delete = fromTriples . deleteByFst (typeFp @a) . toTriples
163{-# INLINE delete #-}
165{-# INLINE delete #-}
168+Update a value at a specific key with the result of the provided function. When
169+the key is not a member of the map, the original map is returned.
171+>>> trmap = fromList @(TypeRepMap Identity) [WrapTypeable $ Identity "a"]
172+>>> lookup @String $ adjust (fmap (++ "ww")) trmap
173+Just (Identity "aww")
175+adjust :: forall a f . Typeable a => (f a -> f a) -> TypeRepMap f -> TypeRepMap f
176+adjust fun tr = case cachedBinarySearch (typeFp @a) (fingerprintAs tr) (fingerprintBs tr) of
178+ Just i -> tr {trAnys = changeAnyArr i (trAnys tr)}
180+ changeAnyArr :: Int -> Array Any -> Array Any
181+ changeAnyArr i trAs = runST $ do
182+ let n = sizeofArray trAs
183+ mutArr <- thawArray trAs 0 n
184+ a <- toAny . fun . fromAny <$> readArray mutArr i
185+ writeArray mutArr i a
186+ freezeArray mutArr 0 n
187+{-# INLINE adjust #-}
165{- | Map over the elements of a 'TypeRepMap'.
189{- | Map over the elements of a 'TypeRepMap'.
167>>> tm = insert (Identity True) $ one (Identity 'a')
191>>> tm = insert (Identity True) $ one (Identity 'a')