Skip to content
This repository was archived by the owner on Oct 4, 2020. It is now read-only.

Commit 62f12b5

Browse files
committed
cleaner lookup code
may also result in slight speed improvement.
1 parent 7bdd5c1 commit 62f12b5

File tree

1 file changed

+71
-67
lines changed

1 file changed

+71
-67
lines changed

src/Data/Map.purs

Lines changed: 71 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -145,78 +145,82 @@ checkValid tree = length (nub (allHeights tree)) == one
145145
allHeights (Two left _ _ right) = map (\n -> n + one) (allHeights left <> allHeights right)
146146
allHeights (Three left _ _ mid _ _ right) = map (\n -> n + one) (allHeights left <> allHeights mid <> allHeights right)
147147

148-
-- | Lookup a value for the specified key
148+
-- | Look up a value for the specified key
149149
lookup :: forall k v. Ord k => k -> Map k v -> Maybe v
150-
lookup = unsafePartial \k tree ->
151-
case tree of
152-
Leaf -> Nothing
153-
_ ->
154-
let comp :: k -> k -> Ordering
155-
comp = compare
156-
in case tree of
157-
Two left k1 v right ->
158-
case comp k k1 of
159-
EQ -> Just v
160-
LT -> lookup k left
161-
_ -> lookup k right
162-
Three left k1 v1 mid k2 v2 right ->
163-
case comp k k1 of
164-
EQ -> Just v1
165-
c1 ->
166-
case c1, comp k k2 of
167-
_ , EQ -> Just v2
168-
LT, _ -> lookup k left
169-
_ , GT -> lookup k right
170-
_ , _ -> lookup k mid
171-
172-
173-
-- | Lookup a value for the specified key, or the greatest one less than it
150+
lookup k = go
151+
where
152+
go Leaf = Nothing
153+
go (Two left k1 v right) =
154+
case compare k k1 of
155+
EQ -> Just v
156+
LT -> go left
157+
_ -> go right
158+
go (Three left k1 v1 mid k2 v2 right) =
159+
case compare k k1 of
160+
EQ -> Just v1
161+
c1 ->
162+
case c1, compare k k2 of
163+
_ , EQ -> Just v2
164+
LT, _ -> go left
165+
_ , GT -> go right
166+
_ , _ -> go mid
167+
168+
169+
-- | Look up a value for the specified key, or the greatest one less than it
174170
lookupLE :: forall k v. Ord k => k -> Map k v -> Maybe { key :: k, value :: v }
175-
lookupLE _ Leaf = Nothing
176-
lookupLE k (Two left k1 v1 right) = case compare k k1 of
177-
EQ -> Just { key: k1, value: v1 }
178-
GT -> Just $ fromMaybe { key: k1, value: v1 } $ lookupLE k right
179-
LT -> lookupLE k left
180-
lookupLE k (Three left k1 v1 mid k2 v2 right) = case compare k k2 of
181-
EQ -> Just { key: k2, value: v2 }
182-
GT -> Just $ fromMaybe { key: k2, value: v2 } $ lookupLE k right
183-
LT -> lookupLE k $ Two left k1 v1 mid
184-
185-
-- | Lookup a value for the greatest key less than the specified key
171+
lookupLE k = go
172+
where
173+
go Leaf = Nothing
174+
go (Two left k1 v1 right) = case compare k k1 of
175+
EQ -> Just { key: k1, value: v1 }
176+
GT -> Just $ fromMaybe { key: k1, value: v1 } $ go right
177+
LT -> go left
178+
go (Three left k1 v1 mid k2 v2 right) = case compare k k2 of
179+
EQ -> Just { key: k2, value: v2 }
180+
GT -> Just $ fromMaybe { key: k2, value: v2 } $ go right
181+
LT -> go $ Two left k1 v1 mid
182+
183+
-- | Look up a value for the greatest key less than the specified key
186184
lookupLT :: forall k v. Ord k => k -> Map k v -> Maybe { key :: k, value :: v }
187-
lookupLT _ Leaf = Nothing
188-
lookupLT k (Two left k1 v1 right) = case compare k k1 of
189-
EQ -> findMax left
190-
GT -> Just $ fromMaybe { key: k1, value: v1 } $ lookupLT k right
191-
LT -> lookupLT k left
192-
lookupLT k (Three left k1 v1 mid k2 v2 right) = case compare k k2 of
193-
EQ -> findMax $ Two left k1 v1 mid
194-
GT -> Just $ fromMaybe { key: k2, value: v2 } $ lookupLT k right
195-
LT -> lookupLT k $ Two left k1 v1 mid
196-
197-
-- | Lookup a value for the specified key, or the least one greater than it
185+
lookupLT k = go
186+
where
187+
go Leaf = Nothing
188+
go (Two left k1 v1 right) = case compare k k1 of
189+
EQ -> findMax left
190+
GT -> Just $ fromMaybe { key: k1, value: v1 } $ go right
191+
LT -> go left
192+
go (Three left k1 v1 mid k2 v2 right) = case compare k k2 of
193+
EQ -> findMax $ Two left k1 v1 mid
194+
GT -> Just $ fromMaybe { key: k2, value: v2 } $ go right
195+
LT -> go $ Two left k1 v1 mid
196+
197+
-- | Look up a value for the specified key, or the least one greater than it
198198
lookupGE :: forall k v. Ord k => k -> Map k v -> Maybe { key :: k, value :: v }
199-
lookupGE _ Leaf = Nothing
200-
lookupGE k (Two left k1 v1 right) = case compare k k1 of
201-
EQ -> Just { key: k1, value: v1 }
202-
LT -> Just $ fromMaybe { key: k1, value: v1 } $ lookupGE k left
203-
GT -> lookupGE k right
204-
lookupGE k (Three left k1 v1 mid k2 v2 right) = case compare k k1 of
205-
EQ -> Just { key: k1, value: v1 }
206-
LT -> Just $ fromMaybe { key: k1, value: v1 } $ lookupGE k left
207-
GT -> lookupGE k $ Two mid k2 v2 right
208-
209-
-- | Lookup a value for the least key greater than the specified key
199+
lookupGE k = go
200+
where
201+
go Leaf = Nothing
202+
go (Two left k1 v1 right) = case compare k k1 of
203+
EQ -> Just { key: k1, value: v1 }
204+
LT -> Just $ fromMaybe { key: k1, value: v1 } $ go left
205+
GT -> go right
206+
go (Three left k1 v1 mid k2 v2 right) = case compare k k1 of
207+
EQ -> Just { key: k1, value: v1 }
208+
LT -> Just $ fromMaybe { key: k1, value: v1 } $ go left
209+
GT -> go $ Two mid k2 v2 right
210+
211+
-- | Look up a value for the least key greater than the specified key
210212
lookupGT :: forall k v. Ord k => k -> Map k v -> Maybe { key :: k, value :: v }
211-
lookupGT _ Leaf = Nothing
212-
lookupGT k (Two left k1 v1 right) = case compare k k1 of
213-
EQ -> findMin right
214-
LT -> Just $ fromMaybe { key: k1, value: v1 } $ lookupGT k left
215-
GT -> lookupGT k right
216-
lookupGT k (Three left k1 v1 mid k2 v2 right) = case compare k k1 of
217-
EQ -> findMin $ Two mid k2 v2 right
218-
LT -> Just $ fromMaybe { key: k1, value: v1 } $ lookupGT k left
219-
GT -> lookupGT k $ Two mid k2 v2 right
213+
lookupGT k = go
214+
where
215+
go Leaf = Nothing
216+
go (Two left k1 v1 right) = case compare k k1 of
217+
EQ -> findMin right
218+
LT -> Just $ fromMaybe { key: k1, value: v1 } $ go left
219+
GT -> go right
220+
go (Three left k1 v1 mid k2 v2 right) = case compare k k1 of
221+
EQ -> findMin $ Two mid k2 v2 right
222+
LT -> Just $ fromMaybe { key: k1, value: v1 } $ go left
223+
GT -> go $ Two mid k2 v2 right
220224

221225
-- | Returns the pair with the greatest key
222226
findMax :: forall k v. Map k v -> Maybe { key :: k, value :: v }

0 commit comments

Comments
 (0)