11
11
{-# LANGUAGE TemplateHaskell #-}
12
12
{-# LANGUAGE TypeApplications #-}
13
13
{-# LANGUAGE TypeFamilies #-}
14
+ {-# LANGUAGE ViewPatterns #-}
14
15
15
16
-- | 'Patch'es on 'Map' that can insert, delete, and move values from one key to
16
17
-- another
17
18
module Data.Patch.MapWithMove
18
19
( module Data.Patch.MapWithMove
19
- , PatchMapWithMove (PatchMapWithMove )
20
+ , PatchMapWithMove
21
+ ( PatchMapWithMove
22
+ , -- | Extract the representation of the 'PatchMapWithMove' as a map of
23
+ -- 'NodeInfo'.
24
+ unPatchMapWithMove
25
+ , ..
26
+ )
20
27
, NodeInfo
21
- , pattern PM. NodeInfo
22
- , PM. _nodeInfo_to
23
- , PM. _nodeInfo_from
28
+ ( NodeInfo
29
+ , _nodeInfo_to
30
+ , _nodeInfo_from
31
+ , ..
32
+ )
33
+ -- TODO export these under the type consructor once GHC is fixed
34
+ -- , From (From_Insert, From_Delete, From_Move)
24
35
) where
25
36
37
+ import Data.Coerce
26
38
import Data.Patch.Class
27
39
import Data.Patch.MapWithPatchingMove
28
40
( PatchMapWithPatchingMove (.. )
@@ -47,16 +59,25 @@ newtype PatchMapWithMove k v = PatchMapWithMove'
47
59
unPatchMapWithMove' :: PatchMapWithPatchingMove k (Proxy v )
48
60
}
49
61
deriving ( Show , Read , Eq , Ord
50
- , Semigroup , Monoid
62
+ , -- | Compose patches having the same effect as applying the
63
+ -- patches in turn: @'applyAlways' (p <> q) == 'applyAlways' p .
64
+ -- 'applyAlways' q@
65
+ Semigroup
66
+ , Monoid
51
67
)
52
68
53
69
{-# COMPLETE PatchMapWithMove #-}
54
70
pattern PatchMapWithMove :: Map k (NodeInfo k v ) -> PatchMapWithMove k v
55
- pattern PatchMapWithMove m = PatchMapWithMove' (PatchMapWithPatchingMove m)
71
+ pattern PatchMapWithMove { unPatchMapWithMove } <- PatchMapWithMove' (PatchMapWithPatchingMove (coerce -> unPatchMapWithMove))
72
+ where PatchMapWithMove m = PatchMapWithMove' $ PatchMapWithPatchingMove $ coerce m
56
73
57
- -- | Extract the internal representation of the 'PatchMapWithMove'
58
- unPatchMapWithMove :: PatchMapWithMove k v -> Map k (PM. NodeInfo k (Proxy v ))
59
- unPatchMapWithMove = unPatchMapWithPatchingMove . unPatchMapWithMove'
74
+ _PatchMapWithMove
75
+ :: Iso
76
+ (PatchMapWithMove k0 v0 )
77
+ (PatchMapWithMove k1 v1 )
78
+ (Map k0 (NodeInfo k0 v0 ))
79
+ (Map k1 (NodeInfo k1 v1 ))
80
+ _PatchMapWithMove = iso unPatchMapWithMove PatchMapWithMove
60
81
61
82
instance Functor (PatchMapWithMove k ) where
62
83
fmap f = runIdentity . traverse (Identity . f)
@@ -66,22 +87,51 @@ instance Foldable (PatchMapWithMove k) where
66
87
67
88
instance Traversable (PatchMapWithMove k ) where
68
89
traverse =
69
- _Wrapping PatchMapWithMove' .
70
- _Wrapping PatchMapWithPatchingMove .
90
+ _PatchMapWithMove .
71
91
traverse .
72
- traverseNodeInfo
92
+ traverse
73
93
74
94
instance FunctorWithIndex k (PatchMapWithMove k )
75
95
instance FoldableWithIndex k (PatchMapWithMove k )
76
96
instance TraversableWithIndex k (PatchMapWithMove k ) where
77
97
itraverse = itraversed . Indexed
78
98
itraversed =
79
- _Wrapping PatchMapWithMove' .>
80
- _Wrapping PatchMapWithPatchingMove .>
99
+ _PatchMapWithMove .>
81
100
itraversed <.
82
- traverseNodeInfo
101
+ traverse
83
102
84
- type NodeInfo k v = PM. NodeInfo k (Proxy v )
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 )
85
135
86
136
type From k v = PM. From k (Proxy v )
87
137
@@ -98,13 +148,10 @@ pattern From_Move k = PM.From_Move k Proxy
98
148
99
149
type To k = PM. To k
100
150
101
- traverseNodeInfo
102
- :: Traversal (NodeInfo k a ) (NodeInfo k b ) a b
103
- traverseNodeInfo = PM. bitraverseNodeInfo pure (\ ~ Proxy -> pure Proxy )
104
151
105
152
-- | Create a 'PatchMapWithMove', validating it
106
153
patchMapWithMove :: Ord k => Map k (NodeInfo k v ) -> Maybe (PatchMapWithMove k v )
107
- patchMapWithMove = fmap PatchMapWithMove' . PM. patchMapWithPatchingMove
154
+ patchMapWithMove = fmap coerce . PM. patchMapWithPatchingMove . coerce
108
155
109
156
-- | Create a 'PatchMapWithMove' that inserts everything in the given 'Map'
110
157
patchMapWithMoveInsertAll :: Map k v -> PatchMapWithMove k v
@@ -142,7 +189,7 @@ deleteMapKey = PatchMapWithMove' . PM.deleteMapKey
142
189
--
143
190
-- __Warning:__ when using this function, you must ensure that the invariants of 'PatchMapWithMove' are preserved; they will not be checked.
144
191
unsafePatchMapWithMove :: Map k (NodeInfo k v ) -> PatchMapWithMove k v
145
- unsafePatchMapWithMove = PatchMapWithMove' . PM. unsafePatchMapWithPatchingMove
192
+ unsafePatchMapWithMove = PatchMapWithMove' . PM. unsafePatchMapWithPatchingMove . coerce
146
193
147
194
-- | Apply the insertions, deletions, and moves to a given 'Map'
148
195
instance Ord k => Patch (PatchMapWithMove k v ) where
@@ -179,18 +226,19 @@ patchThatChangesMap oldByIndex newByIndex = PatchMapWithMove' $
179
226
180
227
-- | Change the 'From' value of a 'NodeInfo'
181
228
nodeInfoMapFrom :: (From k v -> From k v ) -> NodeInfo k v -> NodeInfo k v
182
- nodeInfoMapFrom = PM. nodeInfoMapFrom
229
+ nodeInfoMapFrom = coerce . PM. nodeInfoMapFrom
183
230
184
231
-- | Change the 'From' value of a 'NodeInfo', using a 'Functor' (or
185
232
-- 'Applicative', 'Monad', etc.) action to get the new value
186
233
nodeInfoMapMFrom
187
234
:: Functor f
188
235
=> (From k v -> f (From k v ))
189
236
-> NodeInfo k v -> f (NodeInfo k v )
190
- nodeInfoMapMFrom = PM. nodeInfoMapMFrom
237
+ nodeInfoMapMFrom f = fmap coerce . PM. nodeInfoMapMFrom f . coerce
191
238
192
239
-- | Set the 'To' field of a 'NodeInfo'
193
240
nodeInfoSetTo :: To k -> NodeInfo k v -> NodeInfo k v
194
- nodeInfoSetTo = PM. nodeInfoSetTo
241
+ nodeInfoSetTo = coerce . PM. nodeInfoSetTo
195
242
196
243
makeWrapped ''PatchMapWithMove
244
+ makeWrapped ''NodeInfo
0 commit comments