Skip to content

Commit e79511e

Browse files
author
Ross MacLeod
committed
complete doc comments for Data.Map.Misc, Reflex.FastWeak, Reflex.Patch.DMap, Reflex.Patch.DMapWithMove, Reflex.Patch.IntMap, and Reflex.Patch.Map
1 parent c2d5c14 commit e79511e

File tree

6 files changed

+103
-27
lines changed

6 files changed

+103
-27
lines changed

src/Data/Map/Misc.hs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE LambdaCase #-}
2+
-- |Additional functions for manipulating 'Map's.
23
module Data.Map.Misc
34
(
45
-- * Working with Maps
@@ -10,20 +11,28 @@ module Data.Map.Misc
1011
) where
1112

1213
import Data.Align
13-
import Data.Either
1414
import Data.Map (Map)
1515
import qualified Data.Map as Map
1616
import Data.Maybe
1717
import Data.Set (Set)
1818
import qualified Data.Set as Set
1919
import Data.These
2020

21+
-- |Produce a @'Map' k (Maybe v)@ by comparing two @'Map' k v@s, @old@ and @new@ respectively. @Just@ represents an association present in @new@ and @Nothing@
22+
-- represents an association only present in @old@ but no longer present in @new@.
23+
--
24+
-- Similar to 'diffMap' but doesn't require 'Eq' on the values, thus can't tell if a value has changed or not.
2125
diffMapNoEq :: (Ord k) => Map k v -> Map k v -> Map k (Maybe v)
2226
diffMapNoEq olds news = flip Map.mapMaybe (align olds news) $ \case
2327
This _ -> Just Nothing
2428
These _ new -> Just $ Just new
2529
That new -> Just $ Just new
2630

31+
-- |Produce a @'Map' k (Maybe v)@ by comparing two @'Map' k v@s, @old@ and @new respectively. @Just@ represents an association present in @new@ and either not
32+
-- present in @old@ or where the value has changed. @Nothing@ represents an association only present in @old@ but no longer present in @new@.
33+
--
34+
-- See also 'diffMapNoEq' for a similar but weaker version which does not require 'Eq' on the values but thus can't indicated a value not changing between
35+
-- @old@ and @new@ with @Nothing@.
2736
diffMap :: (Ord k, Eq v) => Map k v -> Map k v -> Map k (Maybe v)
2837
diffMap olds news = flip Map.mapMaybe (align olds news) $ \case
2938
This _ -> Just Nothing
@@ -32,23 +41,29 @@ diffMap olds news = flip Map.mapMaybe (align olds news) $ \case
3241
| otherwise -> Just $ Just new
3342
That new -> Just $ Just new
3443

44+
-- |Given a @'Map' k (Maybe v)@ representing keys to insert/update (@Just@) or delete (@Nothing@), produce a new map from the given input @'Map' k v@.
45+
--
46+
-- See also 'Reflex.Patch.Map' and 'Reflex.Patch.MapWithMove'.
3547
applyMap :: Ord k => Map k (Maybe v) -> Map k v -> Map k v
3648
applyMap patch old = insertions `Map.union` (old `Map.difference` deletions)
3749
where (deletions, insertions) = mapPartitionEithers $ maybeToEither <$> patch
3850
maybeToEither = \case
3951
Nothing -> Left ()
4052
Just r -> Right r
4153

54+
-- |Split a @'Map' k (Either a b)@ into @Map k a@ and @Map k b@, equivalent to @'Map.mapEither' id@
4255
mapPartitionEithers :: Map k (Either a b) -> (Map k a, Map k b)
43-
mapPartitionEithers m = (fromLeft <$> ls, fromRight <$> rs)
44-
where (ls, rs) = Map.partition isLeft m
45-
fromLeft (Left l) = l
46-
fromLeft _ = error "mapPartitionEithers: fromLeft received a Right value; this should be impossible"
47-
fromRight (Right r) = r
48-
fromRight _ = error "mapPartitionEithers: fromRight received a Left value; this should be impossible"
56+
mapPartitionEithers = Map.mapEither id
4957

50-
-- | Apply a map patch to a set
51-
-- > applyMapKeysSet patch (Map.keysSet m) == Map.keysSet (applyMap patch m)
58+
-- |Given a @'Map' k (Maybe v)@ representing keys to insert/update (@Just@) or delete (@Nothing@), produce a new @'Set' k@ from the given input set.
59+
--
60+
-- Equivalent to:
61+
--
62+
-- @
63+
-- applyMapKeysSet patch ('Map.keysSet' m) == 'Map.keysSet' ('applyMap' patch m)
64+
-- @
65+
--
66+
-- but avoids the intervening @Map@ and needs no values.
5267
applyMapKeysSet :: Ord k => Map k (Maybe v) -> Set k -> Set k
5368
applyMapKeysSet patch old = Map.keysSet insertions `Set.union` (old `Set.difference` Map.keysSet deletions)
5469
where (insertions, deletions) = Map.partition isJust patch

src/Reflex/FastWeak.hs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
{-# LANGUAGE ForeignFunctionInterface #-}
66
{-# LANGUAGE JavaScriptFFI #-}
77
#endif
8+
9+
-- |Contains 'FastWeak', a weak pointer to some value, and 'FastWeakTicket' which ensures the value referred to by a 'FastWeak' stays live while the ticket is
10+
-- held (live).
11+
--
12+
-- On GHC or GHCJS when not built with the @fast-weak@ cabal flag, 'FastWeak' is a wrapper around the simple version of 'System.Mem.Weak.Weak' where the key
13+
-- and value are the same.
14+
--
15+
-- On GHCJS when built with the @fast-weak@ cabal flag, 'FastWeak' is implemented directly in JS using @h$FastWeak@ and @h$FastWeakTicket@ which are a
16+
-- nonstandard part of the GHCJS RTS. __FIXME__
817
module Reflex.FastWeak
918
( FastWeakTicket
1019
, FastWeak
@@ -35,29 +44,52 @@ import System.Mem.Weak
3544

3645

3746
#ifdef GHCJS_FAST_WEAK
47+
-- |A 'FastWeak' which has been promoted to a strong reference. 'getFastWeakTicketValue' can be used to get the referred to value without fear of @Nothing,
48+
-- and 'getFastWeakTicketWeak' can be used to get the weak version.
49+
--
50+
-- Implemented by way of special support in the GHCJS RTS, @h$FastWeakTicket@.
3851
newtype FastWeakTicket a = FastWeakTicket JSVal
3952

53+
-- |A reference to some value which can be garbage collected if there are only weak references to the value left.
54+
--
55+
-- 'getFastWeakValue' can be used to try and obtain a strong reference to the value.
56+
--
57+
-- The value in a @FastWeak@ can also be kept alive by obtaining a 'FastWeakTicket' using 'getFastWeakTicket' if the value hasn't been collected yet.
58+
--
59+
-- Implemented by way of special support in the GHCJS RTS, @h$FastWeak@.
4060
newtype FastWeak a = FastWeak JSVal
4161

4262
-- Just designed to mirror JSVal, so that we can unsafeCoerce between the two
4363
data Val a = Val { unVal :: a }
4464

45-
-- | Coerce a JSVal that represents the heap object of a value of type 'a' into a value of type 'a'
65+
-- | Coerce a JSVal that represents the heap object of a value of type @a@ into a value of type @a@
4666
unsafeFromRawJSVal :: JSVal -> a
4767
unsafeFromRawJSVal v = unVal (unsafeCoerce v)
4868

69+
-- | Coerce a heap object of type @a@ into a 'JSVal' which represents that object.
4970
unsafeToRawJSVal :: a -> JSVal
5071
unsafeToRawJSVal v = unsafeCoerce (Val v)
5172
#else
73+
-- |A 'FastWeak' which has been promoted to a strong reference. 'getFastWeakTicketValue' can be used to get the referred to value without fear of @Nothing,
74+
-- and 'getFastWeakTicketWeak' can be used to get the weak version.
5275
data FastWeakTicket a = FastWeakTicket
5376
{ _fastWeakTicket_val :: !a
5477
, _fastWeakTicket_weak :: {-# UNPACK #-} !(Weak a)
5578
}
5679

80+
-- |A reference to some value which can be garbage collected if there are only weak references to the value left.
81+
--
82+
-- 'getFastWeakValue' can be used to try and obtain a strong reference to the value.
83+
--
84+
-- The value in a @FastWeak@ can also be kept alive by obtaining a 'FastWeakTicket' using 'getFastWeakTicket' if the value hasn't been collected yet.
85+
--
86+
-- Synonymous with 'Weak'.
5787
type FastWeak a = Weak a
5888
#endif
5989

60-
-- This needs to be in IO so we know that we've relinquished the ticket
90+
-- |Return the @a@ kept alive by the given 'FastWeakTicket'.
91+
--
92+
-- This needs to be in IO so we know that we've relinquished the ticket.
6193
getFastWeakTicketValue :: FastWeakTicket a -> IO a
6294
#ifdef GHCJS_FAST_WEAK
6395
getFastWeakTicketValue t = do
@@ -69,6 +101,7 @@ foreign import javascript unsafe "$r = $1.val;" js_ticketVal :: FastWeakTicket a
69101
getFastWeakTicketValue = return . _fastWeakTicket_val
70102
#endif
71103

104+
-- |Get the value referred to by a 'FastWeak' if it hasn't yet been collected, or @Nothing@ if it has been collected.
72105
getFastWeakValue :: FastWeak a -> IO (Maybe a)
73106
#ifdef GHCJS_FAST_WEAK
74107
getFastWeakValue w = do
@@ -84,6 +117,8 @@ foreign import javascript unsafe "$r = ($1.ticket === null) ? null : $1.ticket.v
84117
getFastWeakValue = deRefWeak
85118
#endif
86119

120+
-- |Try to create a 'FastWeakTicket' for the given 'FastWeak' which will ensure the referred to value remains alive. Returns @Just@ if the value hasn't been
121+
-- collected and a ticket can therefore be obtained, @Nothing@ if it's been collected.
87122
getFastWeakTicket :: forall a. FastWeak a -> IO (Maybe (FastWeakTicket a))
88123
#ifdef GHCJS_FAST_WEAK
89124
getFastWeakTicket w = do
@@ -103,8 +138,10 @@ getFastWeakTicket w = do
103138
}
104139
#endif
105140

106-
-- I think it's fine if this is lazy - it'll retain the 'a', but so would the output; we just need to make sure it's forced before we start relying on the associated FastWeak to actually be weak
141+
-- |Create a 'FastWeakTicket' directly from a value, creating a 'FastWeak' in the process which can be obtained with 'getFastWeakTicketValue'.
107142
mkFastWeakTicket :: a -> IO (FastWeakTicket a)
143+
-- I think it's fine if this is lazy - it'll retain the 'a', but so would the output; we just need to make sure it's forced before we start relying on the
144+
-- associated FastWeak to actually be weak
108145
#ifdef GHCJS_FAST_WEAK
109146
mkFastWeakTicket v = js_fastWeakTicket (unsafeToRawJSVal v)
110147

@@ -119,11 +156,15 @@ mkFastWeakTicket v = do
119156
}
120157
#endif
121158

159+
-- |Demote a 'FastWeakTicket' which ensures the value is alive to a 'FastWeak' which doesn't. Note that unless the ticket or another for the same 'FastWeak' is
160+
-- held some other way the value might be collected immediately.
161+
getFastWeakTicketWeak :: FastWeakTicket a -> IO (FastWeak a)
122162
-- Needs IO so that it can force the value - otherwise, could end up with a reference to the Ticket, which would retain the value
123163
#ifdef GHCJS_FAST_WEAK
124-
foreign import javascript unsafe "$r = $1.weak;" getFastWeakTicketWeak :: FastWeakTicket a -> IO (FastWeak a)
164+
foreign import javascript unsafe "$r = $1.weak;" getFastWeakTicketWeak' :: FastWeakTicket a -> IO (FastWeak a)
165+
{-# INLINE getFastWeakTicketWeak #-}
166+
getFastWeakTicketWeak = getFastWeakTicketWeak'
125167
#else
126-
getFastWeakTicketWeak :: FastWeakTicket a -> IO (FastWeak a)
127168
getFastWeakTicketWeak = return . _fastWeakTicket_weak
128169
#endif
129170

src/Reflex/Patch/DMap.hs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
{-# LANGUAGE ScopedTypeVariables #-}
66
{-# LANGUAGE StandaloneDeriving #-}
77
{-# LANGUAGE TypeFamilies #-}
8+
-- | 'Patch'es on 'DMap' that consist only of insertions (or overwrites) and deletions.
89
module Reflex.Patch.DMap where
910

1011
import Reflex.Patch.Class
@@ -20,14 +21,15 @@ import qualified Data.Map as Map
2021
import Data.Semigroup (Semigroup (..))
2122
import Data.Some (Some)
2223

23-
-- | A set of changes to a 'DMap'. Any element may be inserted/updated or
24-
-- deleted.
24+
-- | A set of changes to a 'DMap'. Any element may be inserted/updated or deleted. Insertions are represented as @'ComposeMaybe' (Just value)@, while
25+
-- deletions are represented as @'ComposeMaybe' Nothing@.
2526
newtype PatchDMap k v = PatchDMap { unPatchDMap :: DMap k (ComposeMaybe v) }
2627

2728
deriving instance GCompare k => Semigroup (PatchDMap k v)
2829

2930
deriving instance GCompare k => Monoid (PatchDMap k v)
3031

32+
-- |Apply the insertions or deletions to a given 'DMap'.
3133
instance GCompare k => Patch (PatchDMap k v) where
3234
type PatchTarget (PatchDMap k v) = DMap k v
3335
apply (PatchDMap diff) old = Just $! insertions `DMap.union` (old `DMap.difference` deletions) --TODO: return Nothing sometimes --Note: the strict application here is critical to ensuring that incremental merges don't hold onto all their prerequisite events forever; can we make this more robust?
@@ -37,32 +39,38 @@ instance GCompare k => Patch (PatchDMap k v) where
3739
Nothing -> Just $ Constant ()
3840
Just _ -> Nothing
3941

42+
-- | Map a function @v a -> v' a@ over any inserts/updates in the given @'PatchDMap' k v@ to produce a @'PatchDMap' k v'@.
4043
mapPatchDMap :: (forall a. v a -> v' a) -> PatchDMap k v -> PatchDMap k v'
4144
mapPatchDMap f (PatchDMap p) = PatchDMap $ DMap.map (ComposeMaybe . fmap f . getComposeMaybe) p
4245

43-
traversePatchDMap :: Applicative m => (forall a. v a -> m (v' a)) -> PatchDMap k v -> m (PatchDMap k v')
46+
-- | Map an effectful function @v a -> f (v' a)@ over any inserts/updates in the given @'PatchDMap' k v@ to produce a @'PatchDMap' k v'@.
47+
traversePatchDMap :: Applicative f => (forall a. v a -> f (v' a)) -> PatchDMap k v -> f (PatchDMap k v')
4448
traversePatchDMap f = traversePatchDMapWithKey $ const f
4549

50+
-- | Map an effectful function @k a -> v a -> f (v' a)@ over any inserts/updates in the given @'PatchDMap' k v@ to produce a @'PatchDMap' k v'@.
4651
traversePatchDMapWithKey :: Applicative m => (forall a. k a -> v a -> m (v' a)) -> PatchDMap k v -> m (PatchDMap k v')
4752
traversePatchDMapWithKey f (PatchDMap p) = PatchDMap <$> DMap.traverseWithKey (\k (ComposeMaybe v) -> ComposeMaybe <$> traverse (f k) v) p
4853

54+
-- | Weaken a @'PatchDMap' k v@ to a @'PatchMap' (Some k) v'@ using a function @v a -> v'@ to weaken each value contained in the patch.
4955
weakenPatchDMapWith :: (forall a. v a -> v') -> PatchDMap k v -> PatchMap (Some k) v'
5056
weakenPatchDMapWith f (PatchDMap p) = PatchMap $ weakenDMapWith (fmap f . getComposeMaybe) p
5157

52-
patchDMapToPatchMapWith :: (f v -> v') -> PatchDMap (Const2 k v) f -> PatchMap k v'
58+
-- | Convert a weak @'PatchDMap' ('Const2' k a) v@ where the @a@ is known by way of the @Const2@ into a @'PatchMap' k v'@ using a rank 1 function @v a -> v'@.
59+
patchDMapToPatchMapWith :: (v a -> v') -> PatchDMap (Const2 k a) v -> PatchMap k v'
5360
patchDMapToPatchMapWith f (PatchDMap p) = PatchMap $ dmapToMapWith (fmap f . getComposeMaybe) p
5461

55-
const2PatchDMapWith :: forall k v f a. (v -> f a) -> PatchMap k v -> PatchDMap (Const2 k a) f
62+
-- | Convert a @'PatchMap' k v@ into a @'PatchDMap' ('Const2' k a) v'@ using a function @v -> v' a@.
63+
const2PatchDMapWith :: forall k v v' a. (v -> v' a) -> PatchMap k v -> PatchDMap (Const2 k a) v'
5664
const2PatchDMapWith f (PatchMap p) = PatchDMap $ DMap.fromDistinctAscList $ g <$> Map.toAscList p
57-
where g :: (k, Maybe v) -> DSum (Const2 k a) (ComposeMaybe f)
65+
where g :: (k, Maybe v) -> DSum (Const2 k a) (ComposeMaybe v')
5866
g (k, e) = Const2 k :=> ComposeMaybe (f <$> e)
5967

68+
-- | Convert a @'PatchIntMap' v@ into a @'PatchDMap' ('Const2' Int a) v'@ using a function @v -> v' a@.
6069
const2IntPatchDMapWith :: forall v f a. (v -> f a) -> PatchIntMap v -> PatchDMap (Const2 IntMap.Key a) f
6170
const2IntPatchDMapWith f (PatchIntMap p) = PatchDMap $ DMap.fromDistinctAscList $ g <$> IntMap.toAscList p
6271
where g :: (IntMap.Key, Maybe v) -> DSum (Const2 IntMap.Key a) (ComposeMaybe f)
6372
g (k, e) = Const2 k :=> ComposeMaybe (f <$> e)
6473

65-
-- | Get the values that will be deleted if the given patch is applied to the
66-
-- given 'DMap'. Includes values that will be replaced.
74+
-- | Get the values that will be replaced or deleted if the given patch is applied to the given 'DMap'.
6775
getDeletions :: GCompare k => PatchDMap k v -> DMap k v' -> DMap k v'
6876
getDeletions (PatchDMap p) m = DMap.intersectionWithKey (\_ v _ -> v) m p

src/Reflex/Patch/DMapWithMove.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ validationErrorsForPatchDMapWithMove m =
121121
Just $ "unbalanced move at source key " <> gshow src <> " supposedly going to " <> gshow dst <> " but destination key is not moving"
122122
unbalancedMove _ = Nothing
123123

124+
-- |Test whether two @'PatchDMapWithMove' k v@ contain the same patch operations.
124125
instance EqTag k (NodeInfo k v) => Eq (PatchDMapWithMove k v) where
125126
PatchDMapWithMove a == PatchDMapWithMove b = a == b
126127

@@ -362,6 +363,7 @@ const2PatchDMapWithMoveWith f (PatchMapWithMove p) = PatchDMapWithMove $ DMap.fr
362363
, _nodeInfo_to = ComposeMaybe $ Const2 <$> MapWithMove._nodeInfo_to ni
363364
}
364365

366+
-- | Apply the insertions, deletions, and moves to a given 'DMap'.
365367
instance GCompare k => Patch (PatchDMapWithMove k v) where
366368
type PatchTarget (PatchDMapWithMove k v) = DMap k v
367369
apply (PatchDMapWithMove p) old = Just $! insertions `DMap.union` (old `DMap.difference` deletions) --TODO: return Nothing sometimes --Note: the strict application here is critical to ensuring that incremental merges don't hold onto all their prerequisite events forever; can we make this more robust?
@@ -377,8 +379,7 @@ instance GCompare k => Patch (PatchDMapWithMove k v) where
377379
From_Delete -> Just $ Constant ()
378380
_ -> Nothing
379381

380-
-- | Get the values that will be deleted or moved if the given patch is applied
381-
-- to the given 'DMap'.
382+
-- | Get the values that will be replaced, deleted, or moved if the given patch is applied to the given 'DMap'.
382383
getDeletionsAndMoves :: GCompare k => PatchDMapWithMove k v -> DMap k v' -> DMap k (Product v' (ComposeMaybe k))
383384
getDeletionsAndMoves (PatchDMapWithMove p) m = DMap.intersectionWithKey f m p
384385
where f _ v ni = Pair v $ _nodeInfo_to ni

src/Reflex/Patch/IntMap.hs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
{-# LANGUAGE DeriveTraversable #-}
55
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
66
{-# LANGUAGE TypeFamilies #-}
7+
-- |Module containing 'PatchIntMap', a 'Patch' for 'IntMap' which allows for insert/update or delete of associations.
78
module Reflex.Patch.IntMap where
89

910
import Prelude hiding (lookup)
@@ -13,8 +14,11 @@ import Data.Maybe
1314
import Data.Semigroup
1415
import Reflex.Patch.Class
1516

17+
-- |'Patch' for 'IntMap' which represents insertion or deletion of keys in the mapping. Internally represented by 'IntMap (Maybe a)', where @Just@ means
18+
-- insert/update and @Nothing@ means delete.
1619
newtype PatchIntMap a = PatchIntMap (IntMap (Maybe a)) deriving (Functor, Foldable, Traversable, Monoid)
1720

21+
-- |Apply the insertions or deletions to a given 'IntMap'.
1822
instance Patch (PatchIntMap a) where
1923
type PatchTarget (PatchIntMap a) = IntMap a
2024
apply (PatchIntMap p) v = if IntMap.null p then Nothing else Just $
@@ -37,14 +41,22 @@ instance Semigroup (PatchIntMap v) where
3741
GT -> x
3842
#endif
3943

40-
traverseIntMapPatchWithKey :: Applicative t => (Int -> a -> t b) -> PatchIntMap a -> t (PatchIntMap b)
44+
-- |Map a function @Int -> a -> b@ over all @a@s in the given @'PatchIntMap' a@ (that is, all inserts/updates), producing a @PatchIntMap b@.
45+
mapIntMapPatchWithKey :: (Int -> a -> b) -> PatchIntMap a -> PatchIntMap b
46+
mapIntMapPatchWithKey f (PatchIntMap m) = PatchIntMap $ IntMap.mapWithKey (\ k mv -> f k <$> mv) m
47+
48+
-- |Map an effectful function @Int -> a -> f b@ over all @a@s in the given @'PatchIntMap' a@ (that is, all inserts/updates), producing a @f (PatchIntMap b)@.
49+
traverseIntMapPatchWithKey :: Applicative f => (Int -> a -> f b) -> PatchIntMap a -> f (PatchIntMap b)
4150
traverseIntMapPatchWithKey f (PatchIntMap m) = PatchIntMap <$> IntMap.traverseWithKey (\k mv -> traverse (f k) mv) m
4251

52+
-- |Extract all @a@s inserted/updated by the given @'PatchIntMap' a@.
4353
patchIntMapNewElements :: PatchIntMap a -> [a]
4454
patchIntMapNewElements (PatchIntMap m) = catMaybes $ IntMap.elems m
4555

56+
-- |Convert the given @'PatchIntMap' a@ into an @'IntMap' a@ with all the inserts/updates in the given patch.
4657
patchIntMapNewElementsMap :: PatchIntMap a -> IntMap a
4758
patchIntMapNewElementsMap (PatchIntMap m) = IntMap.mapMaybe id m
4859

60+
-- |Subset the given @'IntMap' a@ to contain only the keys that would be deleted by the given @'PatchIntMap' a@.
4961
getDeletions :: PatchIntMap v -> IntMap v' -> IntMap v'
5062
getDeletions (PatchIntMap m) v = IntMap.intersection v m

src/Reflex/Patch/Map.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ import Data.Maybe
1818
newtype PatchMap k v = PatchMap { unPatchMap :: Map k (Maybe v) }
1919
deriving (Show, Read, Eq, Ord)
2020

21-
-- | Applying a 'PatchMap' will update the 'Map' by performing the insertions
22-
-- and deletions specified
21+
-- |Apply the insertions or deletions to a given 'Map'.
2322
instance Ord k => Patch (PatchMap k v) where
2423
type PatchTarget (PatchMap k v) = Map k v
2524
{-# INLINABLE apply #-}

0 commit comments

Comments
 (0)