@@ -18,6 +18,8 @@ module Data.Map
18
18
, findMax
19
19
, deleteMin
20
20
, deleteMax
21
+ , minView
22
+ , maxView
21
23
, foldSubmap
22
24
, submap
23
25
, fromFoldable
@@ -57,7 +59,7 @@ import Data.Traversable (traverse, class Traversable)
57
59
import Data.TraversableWithIndex (class TraversableWithIndex , traverseWithIndex )
58
60
import Data.Tuple (Tuple (Tuple), snd , uncurry )
59
61
import Data.Unfoldable (class Unfoldable , unfoldr )
60
- import Partial.Unsafe (unsafePartial )
62
+ import Partial.Unsafe (unsafePartial , unsafeCrashWith )
61
63
62
64
-- | `Map k v` represents maps from keys of type `k` to values of type `v`.
63
65
data Map k v
@@ -298,28 +300,82 @@ findMin = go Nothing
298
300
-- | Delete the pair with the least key. O(logn).
299
301
-- |
300
302
-- | Return an empty map if the map is empty.
301
- deleteMin :: forall k v . Ord k => Map k v -> Map k v
302
- deleteMin Leaf = Leaf
303
- deleteMin n = down Nil n
303
+ deleteMin :: forall k . Ord k => Map k ~> Map k
304
+ deleteMin = maybe Leaf _.strippedMap <<< minView
305
+
306
+ -- | Delete the pair with the greatest key. O(logn).
307
+ -- |
308
+ -- | Return an empty map if the map is empty.
309
+ deleteMax :: forall k . Ord k => Map k ~> Map k
310
+ deleteMax = maybe Leaf _.strippedMap <<< maxView
311
+
312
+ -- | Retrieves the least key and the value corresponding to that key,
313
+ -- | and the map stripped of that element. O(logn)
314
+ -- |
315
+ -- | Returns Nothing if the map is empty.
316
+ minView
317
+ :: forall k v
318
+ . Ord k
319
+ => Map k v
320
+ -> Maybe { key :: k , value :: v , strippedMap :: Map k v }
321
+ minView Leaf = Nothing
322
+ minView m = Just $ down Nil m
304
323
where
305
- down :: List (TreeContext k v ) -> Map k v -> Map k v
306
- down = unsafePartial \ctx -> case _ of
324
+ down
325
+ :: List (TreeContext k v )
326
+ -> Map k v
327
+ -> { key :: k , value :: v , strippedMap :: Map k v }
328
+ down ctx = case _ of
307
329
Two left k v right ->
308
330
case left, right of
309
- Leaf , Leaf -> deleteUp ctx Leaf
331
+ Leaf , Leaf -> { key: k, value: v, strippedMap: deleteUp ctx Leaf }
310
332
_ , _ -> down (Cons (TwoLeft k v right) ctx) left
311
333
Three left k1 v1 mid k2 v2 right ->
312
334
case left, mid, right of
313
- Leaf , Leaf , Leaf -> fromZipper ctx (Two Leaf k2 v2 Leaf )
335
+ Leaf , Leaf , Leaf ->
336
+ { key: k1
337
+ , value: v1
338
+ , strippedMap: fromZipper ctx (Two Leaf k2 v2 Leaf )
339
+ }
314
340
_ , _ , _ ->
315
341
down (Cons (ThreeLeft k1 v1 mid k2 v2 right) ctx) left
342
+ -- using instead of unsafePartial because of a TCO bug:
343
+ -- https://github.com/purescript/purescript/issues/3157
344
+ Leaf -> unsafeCrashWith " we met a leaf... this shouldn't happen"
316
345
317
- -- | Delete the pair with the greatest key. O(logn).
346
+ -- | Retrieves the greatest key and the value corresponding to that key,
347
+ -- | and the map stripped of that element. O(logn)
318
348
-- |
319
- -- | Return an empty map if the map is empty.
320
- deleteMax :: forall k v . Ord k => Map k v -> Map k v
321
- deleteMax Leaf = Leaf
322
- deleteMax n = removeMaxNode Nil n
349
+ -- | Returns Nothing if the map is empty.
350
+ maxView
351
+ :: forall k v
352
+ . Ord k
353
+ => Map k v
354
+ -> Maybe { key :: k , value :: v , strippedMap :: Map k v }
355
+ maxView Leaf = Nothing
356
+ maxView n = Just $ down Nil n
357
+ where
358
+ down
359
+ :: List (TreeContext k v )
360
+ -> Map k v
361
+ -> { key :: k , value :: v , strippedMap :: Map k v }
362
+ down ctx = case _ of
363
+ Two left k v right ->
364
+ case left, right of
365
+ Leaf , Leaf -> { key: k, value: v, strippedMap: deleteUp ctx Leaf }
366
+ _ , _ -> down (Cons (TwoRight left k v) ctx) right
367
+ Three left k1 v1 mid k2 v2 right ->
368
+ case left, mid, right of
369
+ Leaf , Leaf , Leaf ->
370
+ { key: k2
371
+ , value: v2
372
+ , strippedMap: fromZipper ctx (Two Leaf k1 v1 Leaf )
373
+ }
374
+ _ , _ , _ ->
375
+ down (Cons (ThreeRight left k1 v1 mid k2 v2) ctx) right
376
+ -- using instead of unsafePartial because of a TCO bug:
377
+ -- https://github.com/purescript/purescript/issues/3157
378
+ Leaf -> unsafeCrashWith " we met a leaf... this shouldn't happen"
323
379
324
380
-- | Fold over the entries of a given map where the key is between a lower and
325
381
-- | an upper bound. Passing `Nothing` as either the lower or upper bound
@@ -526,13 +582,13 @@ pop k = down Nil
526
582
Three _ _ _ _ k' v Leaf -> { key: k', value: v }
527
583
Three _ _ _ _ _ _ right -> maxNode right
528
584
529
-
530
- removeMaxNode :: forall k v . Ord k => List ( TreeContext k v ) -> Map k v -> Map k v
531
- removeMaxNode = unsafePartial \ctx -> case _ of
532
- Two Leaf _ _ Leaf -> deleteUp ctx Leaf
533
- Two left k' v right -> removeMaxNode (Cons (TwoRight left k' v) ctx) right
534
- Three Leaf k1 v1 Leaf _ _ Leaf -> deleteUp (Cons (TwoRight Leaf k1 v1) ctx) Leaf
535
- Three left k1 v1 mid k2 v2 right -> removeMaxNode (Cons (ThreeRight left k1 v1 mid k2 v2) ctx) right
585
+ removeMaxNode :: List ( TreeContext k v ) -> Map k v -> Map k v
586
+ removeMaxNode = unsafePartial \ctx m ->
587
+ case m of
588
+ Two Leaf _ _ Leaf -> deleteUp ctx Leaf
589
+ Two left k' v right -> removeMaxNode (Cons (TwoRight left k' v) ctx) right
590
+ Three Leaf k1 v1 Leaf _ _ Leaf -> deleteUp (Cons (TwoRight Leaf k1 v1) ctx) Leaf
591
+ Three left k1 v1 mid k2 v2 right -> removeMaxNode (Cons (ThreeRight left k1 v1 mid k2 v2) ctx) right
536
592
537
593
deleteUp :: forall k v . Ord k => List (TreeContext k v ) -> Map k v -> Map k v
538
594
deleteUp = unsafePartial \ctxs tree ->
0 commit comments