@@ -18,6 +18,8 @@ module Data.Map
1818 , findMax
1919 , deleteMin
2020 , deleteMax
21+ , minView
22+ , maxView
2123 , foldSubmap
2224 , submap
2325 , fromFoldable
@@ -57,7 +59,7 @@ import Data.Traversable (traverse, class Traversable)
5759import Data.TraversableWithIndex (class TraversableWithIndex , traverseWithIndex )
5860import Data.Tuple (Tuple (Tuple), snd , uncurry )
5961import Data.Unfoldable (class Unfoldable , unfoldr )
60- import Partial.Unsafe (unsafePartial )
62+ import Partial.Unsafe (unsafePartial , unsafeCrashWith )
6163
6264-- | `Map k v` represents maps from keys of type `k` to values of type `v`.
6365data Map k v
@@ -298,28 +300,82 @@ findMin = go Nothing
298300-- | Delete the pair with the least key. O(logn).
299301-- |
300302-- | 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
304323 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
307329 Two left k v right ->
308330 case left, right of
309- Leaf , Leaf -> deleteUp ctx Leaf
331+ Leaf , Leaf -> { key: k, value: v, strippedMap: deleteUp ctx Leaf }
310332 _ , _ -> down (Cons (TwoLeft k v right) ctx) left
311333 Three left k1 v1 mid k2 v2 right ->
312334 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+ }
314340 _ , _ , _ ->
315341 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"
316345
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)
318348-- |
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"
323379
324380-- | Fold over the entries of a given map where the key is between a lower and
325381-- | an upper bound. Passing `Nothing` as either the lower or upper bound
@@ -526,13 +582,13 @@ pop k = down Nil
526582 Three _ _ _ _ k' v Leaf -> { key: k', value: v }
527583 Three _ _ _ _ _ _ right -> maxNode right
528584
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
536592
537593deleteUp :: forall k v . Ord k => List (TreeContext k v ) -> Map k v -> Map k v
538594deleteUp = unsafePartial \ctxs tree ->
0 commit comments