Skip to content

Commit be37e5b

Browse files
redfish64gallais
authored andcommitted
Added "lookupBetween" "leftMost" and "rightMost" to Data.SortedMap
1 parent 15ccebb commit be37e5b

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

libs/contrib/Data/SortedMap.idr

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,58 @@ export
319319
mergeLeft : SortedMap k v -> SortedMap k v -> SortedMap k v
320320
mergeLeft = mergeWith const
321321

322+
treeLeftMost : Tree n k v o -> (k,v)
323+
treeLeftMost (Leaf x y) = (x,y)
324+
treeLeftMost (Branch2 x _ _) = treeLeftMost x
325+
treeLeftMost (Branch3 x _ _ _ _) = treeLeftMost x
326+
327+
treeRightMost : Tree n k v o -> (k,v)
328+
treeRightMost (Leaf x y) = (x,y)
329+
treeRightMost (Branch2 _ _ x) = treeRightMost x
330+
treeRightMost (Branch3 _ _ _ _ x) = treeRightMost x
331+
332+
treeLookupBetween : Ord k => k -> Tree n k v o -> (Maybe (k,v),Maybe (k,v))
333+
treeLookupBetween k (Leaf k' v) with (k < k')
334+
treeLookupBetween k (Leaf k' v) | True = (Nothing, Just (k',v))
335+
treeLookupBetween k (Leaf k' v) | False = (Just (k',v), Nothing)
336+
treeLookupBetween k (Branch2 t1 k' t2) with (k < k')
337+
treeLookupBetween k (Branch2 t1 k' t2) | True = -- k < k'
338+
let (lower, upper) = treeLookupBetween k t1 in
339+
(lower, upper <|> pure (treeLeftMost t2))
340+
treeLookupBetween k (Branch2 t1 k' t2) | False = -- k >= k'
341+
let (lower, upper) = treeLookupBetween k t2 in
342+
(lower <|> pure (treeRightMost t1), upper)
343+
treeLookupBetween k (Branch3 t1 k1 t2 k2 t3) with (k < k1)
344+
treeLookupBetween k (Branch3 t1 k1 t2 k2 t3) | True = treeLookupBetween k (Branch2 t1 k1 t2)
345+
treeLookupBetween k (Branch3 t1 k1 t2 k2 t3) | False with (k < k2)
346+
treeLookupBetween k (Branch3 t1 k1 t2 k2 t3) | False | False = treeLookupBetween k (Branch2 t2 k2 t3)
347+
treeLookupBetween k (Branch3 t1 k1 t2 k2 t3) | False | True = --k1 <= k < k2
348+
let (lower, upper) = treeLookupBetween k (Branch2 t1 k1 t2) in
349+
(lower, upper <|> pure (treeLeftMost t3))
350+
351+
||| looks up a key in map, returning the left and right closest values, so that
352+
||| k1 <= k < k2. If at the end of the beginning and/or end of the sorted map, returns
353+
||| nothing appropriately
354+
export
355+
lookupBetween : key -> SortedMap key val -> (Maybe (key,val), Maybe (key,val))
356+
lookupBetween k Empty = (Nothing, Nothing)
357+
lookupBetween k (M _ t) = treeLookupBetween k t
358+
359+
360+
||| Returns the leftmost (least) key and value
361+
export
362+
leftMost : SortedMap key val -> Maybe (key,val)
363+
leftMost Empty = Nothing
364+
leftMost (M _ t) = Just $ treeLeftMost t
365+
366+
367+
||| Returns the rightmost (greatest) key and value
368+
export
369+
rightMost : SortedMap key val -> Maybe (key,val)
370+
rightMost Empty = Nothing
371+
rightMost (M _ t) = Just $ treeRightMost t
372+
373+
322374
export
323375
(Show k, Show v) => Show (SortedMap k v) where
324376
show m = "fromList " ++ (show $ toList m)
@@ -341,3 +393,5 @@ Semigroup v => Semigroup (SortedMap k v) where
341393
export
342394
(Ord k, Semigroup v) => Monoid (SortedMap k v) where
343395
neutral = empty
396+
(&~) : a -> (a -> b) -> b
397+
(&~) x f = f x
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import Data.SortedMap
2+
3+
(&~) : a -> (a -> b) -> b
4+
(&~) x f = f x
5+
6+
infixl 2 &~
7+
8+
testLookupBetween : List (Maybe (Maybe (Int,Int),Maybe (Int,Int)))
9+
testLookupBetween =
10+
let maps : List (((Maybe (Int,Int), Maybe (Int,Int))),(Maybe (Int,Int), Maybe (Int,Int)))
11+
maps =
12+
[
13+
(lookupBetween 1 (singleton 0 10),((Just (0,10)), Nothing))
14+
,(lookupBetween 1 (singleton 0 10 &~ insert 9 90), (Just (0,10), Just (9,90)))
15+
,(lookupBetween 7 (singleton 0 10 &~ insert 5 50 &~ insert 9 90 &~ delete 5), (Just (0,10), Just (9,90)))
16+
,(lookupBetween (-1) (singleton 0 10), (Nothing,Just (0,10)))
17+
,(lookupBetween (-1) (singleton 0 10 &~ insert 9 90), (Nothing,Just (0,10)))
18+
,(lookupBetween (-1) (singleton 0 10 &~ insert 9 90 &~ insert 5 50), (Nothing,Just (0,10)))
19+
,(lookupBetween (-1) (singleton 0 10 &~ insert 6 60), (Nothing,Just (0,10)))
20+
,(lookupBetween 1 (singleton 0 10 &~ insert 9 90 &~ insert 5 50 &~ insert 3 30 &~ insert 7 70 &~ delete 3 &~ delete 7),
21+
(Just (0,10),Just (5,50)))
22+
,(lookupBetween 4 (singleton 0 10 &~ insert 9 90 &~ insert 5 50 &~ insert 3 30 &~ insert 7 70 &~ delete 3 &~ delete 7),
23+
(Just (0,10),Just (5,50)))
24+
,(lookupBetween 6 (singleton 0 10 &~ insert 9 90 &~ insert 5 50 &~ insert 3 30 &~ insert 7 70 &~ delete 3 &~ delete 7),
25+
(Just (5,50),Just (9,90)))
26+
,(lookupBetween 8 (singleton 0 10 &~ insert 9 90 &~ insert 5 50 &~ insert 3 30 &~ insert 7 70 &~ delete 3 &~ delete 7),
27+
(Just (5,50),Just (9,90)))
28+
,(lookupBetween 10 (singleton 0 10 &~ insert 9 90 &~ insert 5 50 &~ insert 3 30 &~ insert 7 70 &~ delete 3 &~ delete 7),
29+
(Just (9,90), Nothing))
30+
,(lookupBetween 100 (singleton 10 100 &~ insert 15 150 &~ insert 40 400 &~ insert 60 600 &~ insert 80 800 &~ insert 90 900),
31+
(Just (90,900), Nothing))
32+
,(lookupBetween 100 (singleton 10 100 &~ insert 15 150 &~ insert 40 400 &~ insert 60 600 &~ insert 80 800 &~ insert 90 900),
33+
(Just (90,900), Nothing))
34+
,(lookupBetween 61 (singleton 10 100 &~ insert 15 150 &~ insert 40 400 &~ insert 60 600 &~ insert 80 800 &~ insert 90 900),
35+
(Just (60,600), Just (80,800)))
36+
]
37+
in
38+
map (\(t,ev) => if t == ev then Nothing else Just t) maps
39+
40+
testLeftRight : List (Maybe (Maybe (Int,Int)))
41+
testLeftRight =
42+
let maps : List (Maybe (Int,Int),Maybe (Int,Int))
43+
maps =
44+
[
45+
(leftMost (singleton 10 100 &~ insert 15 150 &~ insert 40 400 &~ insert 60 600 &~ insert 80 800 &~ insert 90 900), Just (10,100))
46+
,(rightMost (singleton 10 100 &~ insert 15 150 &~ insert 40 400 &~ insert 60 600 &~ insert 80 800 &~ insert 90 900), Just (90,900))
47+
]
48+
in
49+
map (\(t,ev) => if t == ev then Nothing else Just t) maps
50+
51+
main : IO ()
52+
main =
53+
do
54+
ignore $ traverse (printLn . show) testLookupBetween
55+
ignore $ traverse (printLn . show) testLeftRight
56+
57+

tests/contrib/sortedmap_001/expected

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
1/1: Building SortedMapTest (SortedMapTest.idr)
2+
Main> "Nothing"
3+
"Nothing"
4+
"Nothing"
5+
"Nothing"
6+
"Nothing"
7+
"Nothing"
8+
"Nothing"
9+
"Nothing"
10+
"Nothing"
11+
"Nothing"
12+
"Nothing"
13+
"Nothing"
14+
"Nothing"
15+
"Nothing"
16+
"Nothing"
17+
"Nothing"
18+
"Nothing"
19+
Main> Bye for now!

tests/contrib/sortedmap_001/input

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:exec main
2+
:q

tests/contrib/sortedmap_001/run

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
$1 --no-banner --no-color --console-width 0 -p contrib SortedMapTest.idr < input
2+
3+
rm -rf build

0 commit comments

Comments
 (0)