8
8
{-# LANGUAGE PatternGuards #-}
9
9
{-# LANGUAGE PatternSynonyms #-}
10
10
{-# LANGUAGE ScopedTypeVariables #-}
11
+ {-# LANGUAGE StandaloneDeriving #-}
11
12
{-# LANGUAGE TemplateHaskell #-}
12
13
{-# LANGUAGE TypeApplications #-}
13
14
{-# LANGUAGE TypeFamilies #-}
16
17
-- | 'Patch'es on 'Map' that can insert, delete, and move values from one key to
17
18
-- another
18
19
module Data.Patch.MapWithMove
19
- ( module Data.Patch.MapWithMove
20
- , PatchMapWithMove
20
+ ( PatchMapWithMove
21
21
( PatchMapWithMove
22
22
, -- | Extract the representation of the 'PatchMapWithMove' as a map of
23
23
-- 'NodeInfo'.
24
24
unPatchMapWithMove
25
25
, ..
26
26
)
27
+ , patchMapWithMove
28
+ , patchMapWithMoveInsertAll
29
+ , insertMapKey
30
+ , moveMapKey
31
+ , swapMapKey
32
+ , deleteMapKey
33
+ , unsafePatchMapWithMove
34
+ , patchMapWithMoveNewElements
35
+ , patchMapWithMoveNewElementsMap
36
+ , patchThatSortsMapWith
37
+ , patchThatChangesAndSortsMapWith
38
+ , patchThatChangesMap
39
+
40
+ -- * Node Info
27
41
, NodeInfo
28
42
( NodeInfo
29
43
, _nodeInfo_to
30
44
, _nodeInfo_from
31
45
, ..
32
46
)
33
- -- TODO export these under the type consructor once GHC is fixed
34
- -- , From (From_Insert, From_Delete, From_Move)
47
+ , bitraverseNodeInfo
48
+ , nodeInfoMapFrom
49
+ , nodeInfoMapMFrom
50
+ , nodeInfoSetTo
51
+
52
+ -- * From
53
+ , From
54
+ ( From_Insert
55
+ , From_Delete
56
+ , From_Move
57
+ , ..
58
+ )
59
+ , bitraverseFrom
60
+
61
+ -- * To
62
+ , To
35
63
) where
36
64
37
65
import Data.Coerce
66
+ import Data.Kind (Type )
38
67
import Data.Patch.Class
39
68
import Data.Patch.MapWithPatchingMove
40
69
( PatchMapWithPatchingMove (.. )
41
70
)
42
71
import qualified Data.Patch.MapWithPatchingMove as PM
72
+ import Data.Patch.MapWithPatchingMove (To ) -- already a transparent synonym
43
73
44
74
import Control.Lens hiding (from , to )
45
75
import Data.List
@@ -54,7 +84,7 @@ import Data.Traversable (foldMapDefault)
54
84
-- | Patch a Map with additions, deletions, and moves. Invariant: If key @k1@
55
85
-- is coming from @From_Move k2@, then key @k2@ should be going to @Just k1@,
56
86
-- and vice versa. There should never be any unpaired From/To keys.
57
- newtype PatchMapWithMove k v = PatchMapWithMove'
87
+ newtype PatchMapWithMove k ( v :: Type ) = PatchMapWithMove'
58
88
{ -- | Extract the underlying 'PatchMapWithPatchingMove k (Proxy v)'
59
89
unPatchMapWithMove' :: PatchMapWithPatchingMove k (Proxy v )
60
90
}
@@ -66,10 +96,14 @@ newtype PatchMapWithMove k v = PatchMapWithMove'
66
96
, Monoid
67
97
)
68
98
99
+ pattern Coerce :: Coercible a b => a -> b
100
+ pattern Coerce x <- (coerce -> x)
101
+ where Coerce x = coerce x
102
+
69
103
{-# COMPLETE PatchMapWithMove #-}
70
104
pattern PatchMapWithMove :: Map k (NodeInfo k v ) -> PatchMapWithMove k v
71
- pattern PatchMapWithMove { unPatchMapWithMove } <- PatchMapWithMove' ( PatchMapWithPatchingMove (coerce -> unPatchMapWithMove) )
72
- where PatchMapWithMove m = PatchMapWithMove' $ PatchMapWithPatchingMove $ coerce m
105
+ unPatchMapWithMove :: PatchMapWithMove k v -> Map k ( NodeInfo k v )
106
+ pattern PatchMapWithMove { unPatchMapWithMove } = PatchMapWithMove' ( PatchMapWithPatchingMove ( Coerce unPatchMapWithMove))
73
107
74
108
_PatchMapWithMove
75
109
:: Iso
@@ -100,55 +134,6 @@ instance TraversableWithIndex k (PatchMapWithMove k) where
100
134
itraversed <.
101
135
traverse
102
136
103
- newtype NodeInfo k v = NodeInfo' { unNodeInfo' :: PM. NodeInfo k (Proxy v ) }
104
- deriving ( Show , Read , Eq , Ord
105
- )
106
-
107
- {-# COMPLETE NodeInfo #-}
108
- pattern NodeInfo :: To k -> From k v -> NodeInfo k v
109
- pattern NodeInfo { _nodeInfo_to, _nodeInfo_from } =
110
- NodeInfo' (PM. NodeInfo
111
- { PM. _nodeInfo_to = _nodeInfo_to
112
- , PM. _nodeInfo_from = _nodeInfo_from
113
- })
114
-
115
- _NodeInfo
116
- :: Iso
117
- (NodeInfo k0 v0 )
118
- (NodeInfo k1 v1 )
119
- (PM. NodeInfo k0 (Proxy v0 ))
120
- (PM. NodeInfo k1 (Proxy v1 ))
121
- _NodeInfo = iso unNodeInfo' NodeInfo'
122
-
123
- instance Functor (NodeInfo k ) where
124
- fmap f = runIdentity . traverse (Identity . f)
125
-
126
- instance Foldable (NodeInfo k ) where
127
- foldMap = foldMapDefault
128
-
129
- instance Traversable (NodeInfo k ) where
130
- traverse = _NodeInfo . traverseNodeInfo
131
- where
132
- traverseNodeInfo
133
- :: Traversal (PM. NodeInfo k (Proxy a )) (PM. NodeInfo k (Proxy b )) a b
134
- traverseNodeInfo = PM. bitraverseNodeInfo pure (\ ~ Proxy -> pure Proxy )
135
-
136
- type From k v = PM. From k (Proxy v )
137
-
138
- {-# COMPLETE From_Insert, From_Delete, From_Move #-}
139
-
140
- pattern From_Insert :: v -> From k v
141
- pattern From_Insert v = PM. From_Insert v
142
-
143
- pattern From_Delete :: From k v
144
- pattern From_Delete = PM. From_Delete
145
-
146
- pattern From_Move :: k -> From k v
147
- pattern From_Move k = PM. From_Move k Proxy
148
-
149
- type To k = PM. To k
150
-
151
-
152
137
-- | Create a 'PatchMapWithMove', validating it
153
138
patchMapWithMove :: Ord k => Map k (NodeInfo k v ) -> Maybe (PatchMapWithMove k v )
154
139
patchMapWithMove = fmap coerce . PM. patchMapWithPatchingMove . coerce
@@ -224,21 +209,106 @@ patchThatChangesMap :: (Ord k, Ord v) => Map k v -> Map k v -> PatchMapWithMove
224
209
patchThatChangesMap oldByIndex newByIndex = PatchMapWithMove' $
225
210
PM. patchThatChangesMap oldByIndex newByIndex
226
211
212
+ --
213
+ -- NodeInfo
214
+ --
215
+
216
+ -- | Holds the information about each key: where its new value should come from,
217
+ -- and where its old value should go to
218
+ newtype NodeInfo k (v :: Type ) = NodeInfo' { unNodeInfo' :: PM. NodeInfo k (Proxy v ) }
219
+
220
+ deriving instance (Show k , Show p ) => Show (NodeInfo k p )
221
+ deriving instance (Read k , Read p ) => Read (NodeInfo k p )
222
+ deriving instance (Eq k , Eq p ) => Eq (NodeInfo k p )
223
+ deriving instance (Ord k , Ord p ) => Ord (NodeInfo k p )
224
+
225
+ {-# COMPLETE NodeInfo #-}
226
+ pattern NodeInfo :: To k -> From k v -> NodeInfo k v
227
+ _nodeInfo_to :: NodeInfo k v -> To k
228
+ _nodeInfo_from :: NodeInfo k v -> From k v
229
+ pattern NodeInfo { _nodeInfo_to, _nodeInfo_from } =
230
+ NodeInfo' (PM. NodeInfo
231
+ { PM. _nodeInfo_to = _nodeInfo_to
232
+ , PM. _nodeInfo_from = Coerce _nodeInfo_from
233
+ })
234
+
235
+ _NodeInfo
236
+ :: Iso
237
+ (NodeInfo k0 v0 )
238
+ (NodeInfo k1 v1 )
239
+ (PM. NodeInfo k0 (Proxy v0 ))
240
+ (PM. NodeInfo k1 (Proxy v1 ))
241
+ _NodeInfo = iso unNodeInfo' NodeInfo'
242
+
243
+ instance Functor (NodeInfo k ) where
244
+ fmap f = runIdentity . traverse (Identity . f)
245
+
246
+ instance Foldable (NodeInfo k ) where
247
+ foldMap = foldMapDefault
248
+
249
+ instance Traversable (NodeInfo k ) where
250
+ traverse = _NodeInfo . traverseNodeInfo
251
+ where
252
+ traverseNodeInfo
253
+ :: Traversal (PM. NodeInfo k (Proxy a )) (PM. NodeInfo k (Proxy b )) a b
254
+ traverseNodeInfo = PM. bitraverseNodeInfo pure (\ ~ Proxy -> pure Proxy )
255
+
256
+ bitraverseNodeInfo
257
+ :: Applicative f
258
+ => (k0 -> f k1 )
259
+ -> (v0 -> f v1 )
260
+ -> NodeInfo k0 v0 -> f (NodeInfo k1 v1 )
261
+ bitraverseNodeInfo fk fv = fmap coerce
262
+ . PM. bitraverseNodeInfo fk (\ ~ Proxy -> pure Proxy ) fv
263
+ . coerce
264
+
227
265
-- | Change the 'From' value of a 'NodeInfo'
228
266
nodeInfoMapFrom :: (From k v -> From k v ) -> NodeInfo k v -> NodeInfo k v
229
- nodeInfoMapFrom = coerce . PM. nodeInfoMapFrom
267
+ nodeInfoMapFrom f = coerce . PM. nodeInfoMapFrom (unFrom' . f . From' ) . coerce
230
268
231
269
-- | Change the 'From' value of a 'NodeInfo', using a 'Functor' (or
232
270
-- 'Applicative', 'Monad', etc.) action to get the new value
233
271
nodeInfoMapMFrom
234
272
:: Functor f
235
273
=> (From k v -> f (From k v ))
236
274
-> NodeInfo k v -> f (NodeInfo k v )
237
- nodeInfoMapMFrom f = fmap coerce . PM. nodeInfoMapMFrom f . coerce
275
+ nodeInfoMapMFrom f = fmap coerce
276
+ . PM. nodeInfoMapMFrom (fmap unFrom' . f . From' )
277
+ . coerce
238
278
239
279
-- | Set the 'To' field of a 'NodeInfo'
240
280
nodeInfoSetTo :: To k -> NodeInfo k v -> NodeInfo k v
241
281
nodeInfoSetTo = coerce . PM. nodeInfoSetTo
242
282
283
+ --
284
+ -- From
285
+ --
286
+
287
+ -- | Describe how a key's new value should be produced
288
+ newtype From k (v :: Type ) = From' { unFrom' :: PM. From k (Proxy v ) }
289
+
290
+ {-# COMPLETE From_Insert, From_Delete, From_Move #-}
291
+
292
+ -- | Insert the given value here
293
+ pattern From_Insert :: v -> From k v
294
+ pattern From_Insert v = From' (PM. From_Insert v)
295
+
296
+ -- | Delete the existing value, if any, from here
297
+ pattern From_Delete :: From k v
298
+ pattern From_Delete = From' (PM. From_Delete )
299
+
300
+ -- | Move the value here from the given key
301
+ pattern From_Move :: k -> From k v
302
+ pattern From_Move k = From' (PM. From_Move k Proxy )
303
+
304
+ bitraverseFrom
305
+ :: Applicative f
306
+ => (k0 -> f k1 )
307
+ -> (v0 -> f v1 )
308
+ -> From k0 v0 -> f (From k1 v1 )
309
+ bitraverseFrom fk fv = fmap coerce
310
+ . PM. bitraverseFrom fk (\ ~ Proxy -> pure Proxy ) fv
311
+ . coerce
312
+
243
313
makeWrapped ''PatchMapWithMove
244
314
makeWrapped ''NodeInfo
0 commit comments