@@ -116,14 +116,24 @@ checkValid tree = length (nub (allHeights tree)) == one
116116-- | Lookup a value for the specified key
117117lookup :: forall k v . (Ord k ) => k -> Map k v -> Maybe v
118118lookup _ Leaf = Nothing
119- lookup k (Two _ k1 v _) | k == k1 = Just v
120- lookup k (Two left k1 _ _) | k < k1 = lookup k left
121- lookup k (Two _ _ _ right) = lookup k right
122- lookup k (Three _ k1 v1 _ _ _ _) | k == k1 = Just v1
123- lookup k (Three _ _ _ _ k2 v2 _) | k == k2 = Just v2
124- lookup k (Three left k1 _ _ _ _ _) | k < k1 = lookup k left
125- lookup k (Three _ k1 _ mid k2 _ _) | k1 < k && k <= k2 = lookup k mid
126- lookup k (Three _ _ _ _ _ _ right) = lookup k right
119+ lookup k tree =
120+ let comp :: k -> k -> Ordering
121+ comp = compare
122+ in case tree of
123+ Two left k1 v right ->
124+ case comp k k1 of
125+ EQ -> Just v
126+ LT -> lookup k left
127+ _ -> lookup k right
128+ Three left k1 v1 mid k2 v2 right ->
129+ case comp k k1 of
130+ EQ -> Just v1
131+ c1 ->
132+ case c1, comp k k2 of
133+ _ , EQ -> Just v2
134+ LT , _ -> lookup k left
135+ _ , GT -> lookup k right
136+ _ , _ -> lookup k mid
127137
128138-- | Test if a key is a member of a map
129139member :: forall k v . (Ord k ) => k -> Map k v -> Boolean
@@ -138,82 +148,104 @@ data TreeContext k v
138148
139149fromZipper :: forall k v . (Ord k ) => List (TreeContext k v ) -> Map k v -> Map k v
140150fromZipper Nil tree = tree
141- fromZipper (Cons (TwoLeft k1 v1 right) ctx) left = fromZipper ctx (Two left k1 v1 right)
142- fromZipper (Cons (TwoRight left k1 v1) ctx) right = fromZipper ctx (Two left k1 v1 right)
143- fromZipper (Cons (ThreeLeft k1 v1 mid k2 v2 right) ctx) left = fromZipper ctx (Three left k1 v1 mid k2 v2 right)
144- fromZipper (Cons (ThreeMiddle left k1 v1 k2 v2 right) ctx) mid = fromZipper ctx (Three left k1 v1 mid k2 v2 right)
145- fromZipper (Cons (ThreeRight left k1 v1 mid k2 v2) ctx) right = fromZipper ctx (Three left k1 v1 mid k2 v2 right)
151+ fromZipper (Cons x ctx) tree =
152+ case x of
153+ TwoLeft k1 v1 right -> fromZipper ctx (Two tree k1 v1 right)
154+ TwoRight left k1 v1 -> fromZipper ctx (Two left k1 v1 tree)
155+ ThreeLeft k1 v1 mid k2 v2 right -> fromZipper ctx (Three tree k1 v1 mid k2 v2 right)
156+ ThreeMiddle left k1 v1 k2 v2 right -> fromZipper ctx (Three left k1 v1 tree k2 v2 right)
157+ ThreeRight left k1 v1 mid k2 v2 -> fromZipper ctx (Three left k1 v1 mid k2 v2 tree)
146158
147159data KickUp k v = KickUp (Map k v ) k v (Map k v )
148160
149161-- | Insert a key/value pair into a map
150162insert :: forall k v . (Ord k ) => k -> v -> Map k v -> Map k v
151163insert = down Nil
152164 where
165+ comp :: k -> k -> Ordering
166+ comp = compare
167+
153168 down :: List (TreeContext k v ) -> k -> v -> Map k v -> Map k v
154169 down ctx k v Leaf = up ctx (KickUp Leaf k v Leaf )
155- down ctx k v (Two left k1 _ right) | k == k1 = fromZipper ctx (Two left k v right)
156- down ctx k v (Two left k1 v1 right) | k < k1 = down (Cons (TwoLeft k1 v1 right) ctx) k v left
157- down ctx k v (Two left k1 v1 right) = down (Cons (TwoRight left k1 v1) ctx) k v right
158- down ctx k v (Three left k1 _ mid k2 v2 right) | k == k1 = fromZipper ctx (Three left k v mid k2 v2 right)
159- down ctx k v (Three left k1 v1 mid k2 _ right) | k == k2 = fromZipper ctx (Three left k1 v1 mid k v right)
160- down ctx k v (Three left k1 v1 mid k2 v2 right) | k < k1 = down (Cons (ThreeLeft k1 v1 mid k2 v2 right) ctx) k v left
161- down ctx k v (Three left k1 v1 mid k2 v2 right) | k1 < k && k <= k2 = down (Cons (ThreeMiddle left k1 v1 k2 v2 right) ctx) k v mid
162- down ctx k v (Three left k1 v1 mid k2 v2 right) = down (Cons (ThreeRight left k1 v1 mid k2 v2) ctx) k v right
170+ down ctx k v (Two left k1 v1 right) =
171+ case comp k k1 of
172+ EQ -> fromZipper ctx (Two left k v right)
173+ LT -> down (Cons (TwoLeft k1 v1 right) ctx) k v left
174+ _ -> down (Cons (TwoRight left k1 v1) ctx) k v right
175+ down ctx k v (Three left k1 v1 mid k2 v2 right) =
176+ case comp k k1 of
177+ EQ -> fromZipper ctx (Three left k v mid k2 v2 right)
178+ c1 ->
179+ case c1, comp k k2 of
180+ _ , EQ -> fromZipper ctx (Three left k1 v1 mid k v right)
181+ LT , _ -> down (Cons (ThreeLeft k1 v1 mid k2 v2 right) ctx) k v left
182+ GT , LT -> down (Cons (ThreeMiddle left k1 v1 k2 v2 right) ctx) k v mid
183+ _ , _ -> down (Cons (ThreeRight left k1 v1 mid k2 v2) ctx) k v right
163184
164185 up :: List (TreeContext k v ) -> KickUp k v -> Map k v
165186 up Nil (KickUp left k v right) = Two left k v right
166- up (Cons (TwoLeft k1 v1 right) ctx) (KickUp left k v mid) = fromZipper ctx (Three left k v mid k1 v1 right)
167- up (Cons (TwoRight left k1 v1) ctx) (KickUp mid k v right) = fromZipper ctx (Three left k1 v1 mid k v right)
168- up (Cons (ThreeLeft k1 v1 c k2 v2 d) ctx) (KickUp a k v b) = up ctx (KickUp (Two a k v b) k1 v1 (Two c k2 v2 d))
169- up (Cons (ThreeMiddle a k1 v1 k2 v2 d) ctx) (KickUp b k v c) = up ctx (KickUp (Two a k1 v1 b) k v (Two c k2 v2 d))
170- up (Cons (ThreeRight a k1 v1 b k2 v2) ctx) (KickUp c k v d) = up ctx (KickUp (Two a k1 v1 b) k2 v2 (Two c k v d))
187+ up (Cons x ctx) kup =
188+ case x, kup of
189+ TwoLeft k1 v1 right, KickUp left k v mid -> fromZipper ctx (Three left k v mid k1 v1 right)
190+ TwoRight left k1 v1, KickUp mid k v right -> fromZipper ctx (Three left k1 v1 mid k v right)
191+ ThreeLeft k1 v1 c k2 v2 d, KickUp a k v b -> up ctx (KickUp (Two a k v b) k1 v1 (Two c k2 v2 d))
192+ ThreeMiddle a k1 v1 k2 v2 d, KickUp b k v c -> up ctx (KickUp (Two a k1 v1 b) k v (Two c k2 v2 d))
193+ ThreeRight a k1 v1 b k2 v2, KickUp c k v d -> up ctx (KickUp (Two a k1 v1 b) k2 v2 (Two c k v d))
171194
172195-- | Delete a key and its corresponding value from a map
173196delete :: forall k v . (Ord k ) => k -> Map k v -> Map k v
174197delete = down Nil
175198 where
199+ comp :: k -> k -> Ordering
200+ comp = compare
201+
176202 down :: List (TreeContext k v ) -> k -> Map k v -> Map k v
177203 down ctx _ Leaf = fromZipper ctx Leaf
178- down ctx k (Two Leaf k1 _ Leaf )
179- | k == k1 = up ctx Leaf
180- down ctx k (Two left k1 v1 right)
181- | k == k1 = let max = maxNode left
182- in removeMaxNode (Cons (TwoLeft max.key max.value right) ctx) left
183- | k < k1 = down (Cons (TwoLeft k1 v1 right) ctx) k left
184- | otherwise = down (Cons (TwoRight left k1 v1) ctx) k right
185- down ctx k (Three Leaf k1 v1 Leaf k2 v2 Leaf )
186- | k == k1 = fromZipper ctx (Two Leaf k2 v2 Leaf )
187- | k == k2 = fromZipper ctx (Two Leaf k1 v1 Leaf )
188- down ctx k (Three left k1 v1 mid k2 v2 right)
189- | k == k1 = let max = maxNode left
190- in removeMaxNode (Cons (ThreeLeft max.key max.value mid k2 v2 right) ctx) left
191- | k == k2 = let max = maxNode mid
192- in removeMaxNode (Cons (ThreeMiddle left k1 v1 max.key max.value right) ctx) mid
193- | k < k1 = down (Cons (ThreeLeft k1 v1 mid k2 v2 right) ctx) k left
194- | k1 < k && k < k2 = down (Cons (ThreeMiddle left k1 v1 k2 v2 right) ctx) k mid
195- | otherwise = down (Cons (ThreeRight left k1 v1 mid k2 v2) ctx) k right
204+ down ctx k (Two left k1 v1 right) =
205+ case right, comp k k1 of
206+ Leaf , EQ -> up ctx Leaf
207+ _ , EQ -> let max = maxNode left
208+ in removeMaxNode (Cons (TwoLeft max.key max.value right) ctx) left
209+ _ , LT -> down (Cons (TwoLeft k1 v1 right) ctx) k left
210+ _ , _ -> down (Cons (TwoRight left k1 v1) ctx) k right
211+ down ctx k (Three left k1 v1 mid k2 v2 right) =
212+ let leaves =
213+ case left, mid, right of
214+ Leaf , Leaf , Leaf -> true
215+ _ , _ , _ -> false
216+ in case leaves, comp k k1, comp k k2 of
217+ true , EQ , _ -> fromZipper ctx (Two Leaf k2 v2 Leaf )
218+ true , _ , EQ -> fromZipper ctx (Two Leaf k1 v1 Leaf )
219+ _ , EQ , _ -> let max = maxNode left
220+ in removeMaxNode (Cons (ThreeLeft max.key max.value mid k2 v2 right) ctx) left
221+ _ , _ , EQ -> let max = maxNode mid
222+ in removeMaxNode (Cons (ThreeMiddle left k1 v1 max.key max.value right) ctx) mid
223+ _ , LT , _ -> down (Cons (ThreeLeft k1 v1 mid k2 v2 right) ctx) k left
224+ _ , GT , LT -> down (Cons (ThreeMiddle left k1 v1 k2 v2 right) ctx) k mid
225+ _ , _ , _ -> down (Cons (ThreeRight left k1 v1 mid k2 v2) ctx) k right
196226
197227 up :: List (TreeContext k v ) -> Map k v -> Map k v
198228 up Nil tree = tree
199- up (Cons (TwoLeft k1 v1 Leaf ) ctx) Leaf = fromZipper ctx (Two Leaf k1 v1 Leaf )
200- up (Cons (TwoRight Leaf k1 v1) ctx) Leaf = fromZipper ctx (Two Leaf k1 v1 Leaf )
201- up (Cons (TwoLeft k1 v1 (Two m k2 v2 r)) ctx) l = up ctx (Three l k1 v1 m k2 v2 r)
202- up (Cons (TwoRight (Two l k1 v1 m) k2 v2) ctx) r = up ctx (Three l k1 v1 m k2 v2 r)
203- up (Cons (TwoLeft k1 v1 (Three b k2 v2 c k3 v3 d)) ctx) a = fromZipper ctx (Two (Two a k1 v1 b) k2 v2 (Two c k3 v3 d))
204- up (Cons (TwoRight (Three a k1 v1 b k2 v2 c) k3 v3) ctx) d = fromZipper ctx (Two (Two a k1 v1 b) k2 v2 (Two c k3 v3 d))
205- up (Cons (ThreeLeft k1 v1 Leaf k2 v2 Leaf ) ctx) Leaf = fromZipper ctx (Three Leaf k1 v1 Leaf k2 v2 Leaf )
206- up (Cons (ThreeMiddle Leaf k1 v1 k2 v2 Leaf ) ctx) Leaf = fromZipper ctx (Three Leaf k1 v1 Leaf k2 v2 Leaf )
207- up (Cons (ThreeRight Leaf k1 v1 Leaf k2 v2) ctx) Leaf = fromZipper ctx (Three Leaf k1 v1 Leaf k2 v2 Leaf )
208- up (Cons (ThreeLeft k1 v1 (Two b k2 v2 c) k3 v3 d) ctx) a = fromZipper ctx (Two (Three a k1 v1 b k2 v2 c) k3 v3 d)
209- up (Cons (ThreeMiddle (Two a k1 v1 b) k2 v2 k3 v3 d) ctx) c = fromZipper ctx (Two (Three a k1 v1 b k2 v2 c) k3 v3 d)
210- up (Cons (ThreeMiddle a k1 v1 k2 v2 (Two c k3 v3 d)) ctx) b = fromZipper ctx (Two a k1 v1 (Three b k2 v2 c k3 v3 d))
211- up (Cons (ThreeRight a k1 v1 (Two b k2 v2 c) k3 v3) ctx) d = fromZipper ctx (Two a k1 v1 (Three b k2 v2 c k3 v3 d))
212- up (Cons (ThreeLeft k1 v1 (Three b k2 v2 c k3 v3 d) k4 v4 e) ctx) a = fromZipper ctx (Three (Two a k1 v1 b) k2 v2 (Two c k3 v3 d) k4 v4 e)
213- up (Cons (ThreeMiddle (Three a k1 v1 b k2 v2 c) k3 v3 k4 v4 e) ctx) d = fromZipper ctx (Three (Two a k1 v1 b) k2 v2 (Two c k3 v3 d) k4 v4 e)
214- up (Cons (ThreeMiddle a k1 v1 k2 v2 (Three c k3 v3 d k4 v4 e)) ctx) b = fromZipper ctx (Three a k1 v1 (Two b k2 v2 c) k3 v3 (Two d k4 v4 e))
215- up (Cons (ThreeRight a k1 v1 (Three b k2 v2 c k3 v3 d) k4 v4) ctx) e = fromZipper ctx (Three a k1 v1 (Two b k2 v2 c) k3 v3 (Two d k4 v4 e))
216- up _ _ = unsafeThrow " Impossible case in 'up'"
229+ up (Cons x ctx) tree =
230+ case x, tree of
231+ TwoLeft k1 v1 Leaf , Leaf -> fromZipper ctx (Two Leaf k1 v1 Leaf )
232+ TwoRight Leaf k1 v1, Leaf -> fromZipper ctx (Two Leaf k1 v1 Leaf )
233+ TwoLeft k1 v1 (Two m k2 v2 r), l -> up ctx (Three l k1 v1 m k2 v2 r)
234+ TwoRight (Two l k1 v1 m) k2 v2, r -> up ctx (Three l k1 v1 m k2 v2 r)
235+ TwoLeft k1 v1 (Three b k2 v2 c k3 v3 d), a -> fromZipper ctx (Two (Two a k1 v1 b) k2 v2 (Two c k3 v3 d))
236+ TwoRight (Three a k1 v1 b k2 v2 c) k3 v3, d -> fromZipper ctx (Two (Two a k1 v1 b) k2 v2 (Two c k3 v3 d))
237+ ThreeLeft k1 v1 Leaf k2 v2 Leaf , Leaf -> fromZipper ctx (Three Leaf k1 v1 Leaf k2 v2 Leaf )
238+ ThreeMiddle Leaf k1 v1 k2 v2 Leaf , Leaf -> fromZipper ctx (Three Leaf k1 v1 Leaf k2 v2 Leaf )
239+ ThreeRight Leaf k1 v1 Leaf k2 v2, Leaf -> fromZipper ctx (Three Leaf k1 v1 Leaf k2 v2 Leaf )
240+ ThreeLeft k1 v1 (Two b k2 v2 c) k3 v3 d, a -> fromZipper ctx (Two (Three a k1 v1 b k2 v2 c) k3 v3 d)
241+ ThreeMiddle (Two a k1 v1 b) k2 v2 k3 v3 d, c -> fromZipper ctx (Two (Three a k1 v1 b k2 v2 c) k3 v3 d)
242+ ThreeMiddle a k1 v1 k2 v2 (Two c k3 v3 d), b -> fromZipper ctx (Two a k1 v1 (Three b k2 v2 c k3 v3 d))
243+ ThreeRight a k1 v1 (Two b k2 v2 c) k3 v3, d -> fromZipper ctx (Two a k1 v1 (Three b k2 v2 c k3 v3 d))
244+ ThreeLeft k1 v1 (Three b k2 v2 c k3 v3 d) k4 v4 e, a -> fromZipper ctx (Three (Two a k1 v1 b) k2 v2 (Two c k3 v3 d) k4 v4 e)
245+ ThreeMiddle (Three a k1 v1 b k2 v2 c) k3 v3 k4 v4 e, d -> fromZipper ctx (Three (Two a k1 v1 b) k2 v2 (Two c k3 v3 d) k4 v4 e)
246+ ThreeMiddle a k1 v1 k2 v2 (Three c k3 v3 d k4 v4 e), b -> fromZipper ctx (Three a k1 v1 (Two b k2 v2 c) k3 v3 (Two d k4 v4 e))
247+ ThreeRight a k1 v1 (Three b k2 v2 c k3 v3 d) k4 v4, e -> fromZipper ctx (Three a k1 v1 (Two b k2 v2 c) k3 v3 (Two d k4 v4 e))
248+ _, _ -> unsafeThrow " Impossible case in 'up'"
217249
218250 maxNode :: Map k v -> { key :: k , value :: v }
219251 maxNode (Two _ k v Leaf ) = { key: k, value: v }
0 commit comments