Portability | GHC |
---|---|
Stability | experimental |
Maintainer | bos@serpentine.com |
Safe Haskell | None |
A crit-bit tree that does not evaluate its values by default.
For every n key-value pairs stored, a crit-bit tree uses n-1 internal nodes, for a total of 2n-1 internal nodes and leaves.
- class Eq k => CritBitKey k where
- data CritBit k v
- (!) :: CritBitKey k => CritBit k v -> k -> v
- (\\) :: CritBitKey k => CritBit k v -> CritBit k w -> CritBit k v
- null :: CritBit k v -> Bool
- size :: CritBit k v -> Int
- member :: CritBitKey k => k -> CritBit k v -> Bool
- notMember :: CritBitKey k => k -> CritBit k v -> Bool
- lookup :: CritBitKey k => k -> CritBit k v -> Maybe v
- findWithDefault :: CritBitKey k => v -> k -> CritBit k v -> v
- lookupGT :: CritBitKey k => k -> CritBit k v -> Maybe (k, v)
- lookupGE :: CritBitKey k => k -> CritBit k v -> Maybe (k, v)
- lookupLT :: CritBitKey k => k -> CritBit k v -> Maybe (k, v)
- lookupLE :: CritBitKey k => k -> CritBit k v -> Maybe (k, v)
- empty :: CritBit k v
- singleton :: k -> v -> CritBit k v
- insert :: CritBitKey k => k -> v -> CritBit k v -> CritBit k v
- insertWith :: CritBitKey k => (v -> v -> v) -> k -> v -> CritBit k v -> CritBit k v
- insertWithKey :: CritBitKey k => (k -> v -> v -> v) -> k -> v -> CritBit k v -> CritBit k v
- insertLookupWithKey :: CritBitKey k => (k -> v -> v -> v) -> k -> v -> CritBit k v -> (Maybe v, CritBit k v)
- delete :: CritBitKey k => k -> CritBit k v -> CritBit k v
- adjust :: CritBitKey k => (v -> v) -> k -> CritBit k v -> CritBit k v
- adjustWithKey :: CritBitKey k => (k -> v -> v) -> k -> CritBit k v -> CritBit k v
- update :: CritBitKey k => (v -> Maybe v) -> k -> CritBit k v -> CritBit k v
- updateWithKey :: CritBitKey k => (k -> v -> Maybe v) -> k -> CritBit k v -> CritBit k v
- updateLookupWithKey :: CritBitKey k => (k -> v -> Maybe v) -> k -> CritBit k v -> (Maybe v, CritBit k v)
- alter :: CritBitKey k => (Maybe v -> Maybe v) -> k -> CritBit k v -> CritBit k v
- union :: CritBitKey k => CritBit k v -> CritBit k v -> CritBit k v
- unionWith :: CritBitKey k => (v -> v -> v) -> CritBit k v -> CritBit k v -> CritBit k v
- unionWithKey :: CritBitKey k => (k -> v -> v -> v) -> CritBit k v -> CritBit k v -> CritBit k v
- unions :: CritBitKey k => [CritBit k v] -> CritBit k v
- unionsWith :: CritBitKey k => (v -> v -> v) -> [CritBit k v] -> CritBit k v
- unionL :: CritBitKey k => CritBit k v -> CritBit k v -> CritBit k v
- unionR :: CritBitKey k => CritBit k v -> CritBit k v -> CritBit k v
- difference :: CritBitKey k => CritBit k v -> CritBit k w -> CritBit k v
- differenceWith :: CritBitKey k => (v -> w -> Maybe v) -> CritBit k v -> CritBit k w -> CritBit k v
- differenceWithKey :: CritBitKey k => (k -> v -> w -> Maybe v) -> CritBit k v -> CritBit k w -> CritBit k v
- intersection :: CritBitKey k => CritBit k v -> CritBit k w -> CritBit k v
- intersectionWith :: CritBitKey k => (v -> w -> x) -> CritBit k v -> CritBit k w -> CritBit k x
- intersectionWithKey :: CritBitKey k => (k -> v -> w -> x) -> CritBit k v -> CritBit k w -> CritBit k x
- map :: CritBitKey k => (v -> w) -> CritBit k v -> CritBit k w
- mapWithKey :: (k -> v -> w) -> CritBit k v -> CritBit k w
- traverseWithKey :: (CritBitKey k, Applicative t) => (k -> v -> t w) -> CritBit k v -> t (CritBit k w)
- mapAccum :: CritBitKey k => (a -> v -> (a, w)) -> a -> CritBit k v -> (a, CritBit k w)
- mapAccumWithKey :: CritBitKey k => (a -> k -> v -> (a, w)) -> a -> CritBit k v -> (a, CritBit k w)
- mapAccumRWithKey :: CritBitKey k => (a -> k -> v -> (a, w)) -> a -> CritBit k v -> (a, CritBit k w)
- mapKeys :: CritBitKey k2 => (k1 -> k2) -> CritBit k1 v -> CritBit k2 v
- mapKeysWith :: CritBitKey k2 => (v -> v -> v) -> (k1 -> k2) -> CritBit k1 v -> CritBit k2 v
- mapKeysMonotonic :: CritBitKey k => (a -> k) -> CritBit a v -> CritBit k v
- foldl :: (a -> v -> a) -> a -> CritBit k v -> a
- foldr :: (v -> a -> a) -> a -> CritBit k v -> a
- foldlWithKey :: (a -> k -> v -> a) -> a -> CritBit k v -> a
- foldrWithKey :: (k -> v -> a -> a) -> a -> CritBit k v -> a
- foldl' :: (a -> v -> a) -> a -> CritBit k v -> a
- foldr' :: (v -> a -> a) -> a -> CritBit k v -> a
- foldlWithKey' :: (a -> k -> v -> a) -> a -> CritBit k v -> a
- foldrWithKey' :: (k -> v -> a -> a) -> a -> CritBit k v -> a
- elems :: CritBit k v -> [v]
- keys :: CritBit k v -> [k]
- assocs :: CritBit k v -> [(k, v)]
- keysSet :: CritBit k v -> Set k
- fromSet :: (k -> v) -> Set k -> CritBit k v
- toList :: CritBit k v -> [(k, v)]
- fromList :: CritBitKey k => [(k, v)] -> CritBit k v
- fromListWith :: CritBitKey k => (v -> v -> v) -> [(k, v)] -> CritBit k v
- fromListWithKey :: CritBitKey k => (k -> v -> v -> v) -> [(k, v)] -> CritBit k v
- toAscList :: CritBit k v -> [(k, v)]
- toDescList :: CritBit k v -> [(k, v)]
- fromAscList :: CritBitKey k => [(k, a)] -> CritBit k a
- fromAscListWith :: CritBitKey k => (a -> a -> a) -> [(k, a)] -> CritBit k a
- fromAscListWithKey :: CritBitKey k => (k -> a -> a -> a) -> [(k, a)] -> CritBit k a
- fromDistinctAscList :: CritBitKey k => [(k, a)] -> CritBit k a
- filter :: (v -> Bool) -> CritBit k v -> CritBit k v
- filterWithKey :: (k -> v -> Bool) -> CritBit k v -> CritBit k v
- partition :: CritBitKey k => (v -> Bool) -> CritBit k v -> (CritBit k v, CritBit k v)
- partitionWithKey :: CritBitKey k => (k -> v -> Bool) -> CritBit k v -> (CritBit k v, CritBit k v)
- mapMaybe :: (a -> Maybe b) -> CritBit k a -> CritBit k b
- mapMaybeWithKey :: (k -> v -> Maybe v') -> CritBit k v -> CritBit k v'
- mapEither :: (a -> Either b c) -> CritBit k a -> (CritBit k b, CritBit k c)
- mapEitherWithKey :: (k -> v -> Either v1 v2) -> CritBit k v -> (CritBit k v1, CritBit k v2)
- split :: CritBitKey k => k -> CritBit k v -> (CritBit k v, CritBit k v)
- splitLookup :: CritBitKey k => k -> CritBit k v -> (CritBit k v, Maybe v, CritBit k v)
- isSubmapOf :: (CritBitKey k, Eq v) => CritBit k v -> CritBit k v -> Bool
- isSubmapOfBy :: CritBitKey k => (a -> b -> Bool) -> CritBit k a -> CritBit k b -> Bool
- isProperSubmapOf :: (CritBitKey k, Eq v) => CritBit k v -> CritBit k v -> Bool
- isProperSubmapOfBy :: CritBitKey k => (a -> b -> Bool) -> CritBit k a -> CritBit k b -> Bool
- findMin :: CritBit k v -> (k, v)
- findMax :: CritBit k v -> (k, v)
- deleteMin :: CritBit k v -> CritBit k v
- deleteMax :: CritBit k v -> CritBit k v
- deleteFindMin :: CritBit k v -> ((k, v), CritBit k v)
- deleteFindMax :: CritBit k v -> ((k, v), CritBit k v)
- updateMin :: (v -> Maybe v) -> CritBit k v -> CritBit k v
- updateMax :: (v -> Maybe v) -> CritBit k v -> CritBit k v
- updateMinWithKey :: (k -> v -> Maybe v) -> CritBit k v -> CritBit k v
- updateMaxWithKey :: (k -> v -> Maybe v) -> CritBit k v -> CritBit k v
- minView :: CritBit k v -> Maybe (v, CritBit k v)
- maxView :: CritBit k v -> Maybe (v, CritBit k v)
- minViewWithKey :: CritBit k v -> Maybe ((k, v), CritBit k v)
- maxViewWithKey :: CritBit k v -> Maybe ((k, v), CritBit k v)
Types
class Eq k => CritBitKey k whereSource
A type that can be used as a key in a crit-bit tree.
We use 9 bits to represent 8-bit bytes so that we can distinguish between an interior byte that is zero (which must have the 9th bit set) and a byte past the end of the input (which must not have the 9th bit set).
Without this trick, the critical bit calculations would fail on zero bytes within a string, and our tree would be unable to handle arbitrary binary data.
Return the number of bytes used by this key.
For reasonable performance, implementations must be inlined and O(1).
getByte :: k -> Int -> Word16Source
Return the byte at the given offset (counted in bytes) of this key, bitwise-ORed with 256. If the offset is past the end of the key, return zero.
For reasonable performance, implementations must be inlined and O(1).
A crit-bit tree.
Operators
(!) :: CritBitKey k => CritBit k v -> k -> vSource
O(k). Find the value at a key.
Calls error
when the element can not be found.
fromList [("a",5), ("b",3)] ! "c" Error: element not in the map fromList [("a",5), ("b",3)] ! "a" == 5
(\\) :: CritBitKey k => CritBit k v -> CritBit k w -> CritBit k vSource
Same as difference
.
Query
null :: CritBit k v -> BoolSource
O(1). Is the map empty?
null (empty) == True null (singleton 1 'a') == False
size :: CritBit k v -> IntSource
O(n). The number of elements in the map.
size empty == 0 size (singleton "a" 1) == 1 size (fromList [("a",1), ("c",2), ("b",3)]) == 3
member :: CritBitKey k => k -> CritBit k v -> BoolSource
O(k). Is the key a member of the map?
member "a" (fromList [("a",5), ("b",3)]) == True member "c" (fromList [("a",5), ("b",3)]) == False
See also notMember
.
notMember :: CritBitKey k => k -> CritBit k v -> BoolSource
O(k). Is the key not a member of the map?
notMember "a" (fromList [("a",5), ("b",3)]) == False notMember "c" (fromList [("a",5), ("b",3)]) == True
See also member
.
lookup :: CritBitKey k => k -> CritBit k v -> Maybe vSource
O(k). Lookup the value at a key in the map.
The function will return the corresponding value as (
,
or Just
value)Nothing
if the key isn't in the map.
An example of using lookup
:
{-# LANGUAGE OverloadedStrings #-} import Data.Text import Prelude hiding (lookup) import Data.CritBit.Map.Lazy employeeDept, deptCountry, countryCurrency :: CritBit Text Text employeeDept = fromList [("John","Sales"), ("Bob","IT")] deptCountry = fromList [("IT","USA"), ("Sales","France")] countryCurrency = fromList [("USA", "Dollar"), ("France", "Euro")] employeeCurrency :: Text -> Maybe Text employeeCurrency name = do dept <- lookup name employeeDept country <- lookup dept deptCountry lookup country countryCurrency main = do putStrLn $ "John's currency: " ++ show (employeeCurrency "John") putStrLn $ "Pete's currency: " ++ show (employeeCurrency "Pete")
The output of this program:
John's currency: Just "Euro" Pete's currency: Nothing
:: CritBitKey k | |
=> v | Default value to return if lookup fails. |
-> k | |
-> CritBit k v | |
-> v |
O(k). Returns the value associated with the given key, or the given default value if the key is not in the map.
findWithDefault 1 "x" (fromList [("a",5), ("b",3)]) == 1 findWithDefault 1 "a" (fromList [("a",5), ("b",3)]) == 5
lookupGT :: CritBitKey k => k -> CritBit k v -> Maybe (k, v)Source
O(k). Find smallest key greater than the given one and return the corresponding (key, value) pair.
lookupGT "aa" (fromList [("a",3), ("b",5)]) == Just ("b",5) lookupGT "b" (fromList [("a",3), ("b",5)]) == Nothing
lookupGE :: CritBitKey k => k -> CritBit k v -> Maybe (k, v)Source
O(k). Find smallest key greater than or equal to the given one and return the corresponding (key, value) pair.
lookupGE "aa" (fromList [("a",3), ("b",5)]) == Just("b",5) lookupGE "b" (fromList [("a",3), ("b",5)]) == Just("b",5) lookupGE "bb" (fromList [("a",3), ("b",5)]) == Nothing
lookupLT :: CritBitKey k => k -> CritBit k v -> Maybe (k, v)Source
O(k). Find largest key smaller than the given one and return the corresponding (key, value) pair.
lookupLT "aa" (fromList [("a",3), ("b",5)]) == Just ("a",3) lookupLT "a" (fromList [("a",3), ("b",5)]) == Nothing
lookupLE :: CritBitKey k => k -> CritBit k v -> Maybe (k, v)Source
O(k). Find largest key smaller than or equal to the given one and return the corresponding (key, value) pair.
lookupGE "bb" (fromList [("aa",3), ("b",5)]) == Just("b",5) lookupGE "aa" (fromList [("aa",3), ("b",5)]) == Just("aa",5) lookupGE "a" (fromList [("aa",3), ("b",5)]) == Nothing
Construction
singleton :: k -> v -> CritBit k vSource
O(1). A map with a single element.
singleton "a" 1 == fromList [("a",1)]
Insertion
insert :: CritBitKey k => k -> v -> CritBit k v -> CritBit k vSource
O(k). Insert a new key and value in the map. If the key is
already present in the map, the associated value is replaced with
the supplied value. insert
is equivalent to
.
insertWith
const
insert "b" 7 (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",7)] insert "x" 7 (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3), ("x",7)] insert "x" 5 empty == singleton "x" 5
insertWith :: CritBitKey k => (v -> v -> v) -> k -> v -> CritBit k v -> CritBit k vSource
O(k). Insert with a function, combining new value and old value.
will insert the pair (key, value) into insertWith
f key value cbcb
if key does
not exist in the map. If the key does exist, the function will
insert the pair (key, f new_value old_value)
.
insertWith (+) "a" 1 (fromList [("a",5), ("b",3)]) == fromList [("a",6), ("b",3)] insertWith (+) "c" 7 (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3), ("c",7)] insertWith (+) "x" 5 empty == singleton "x" 5
insertWithKey :: CritBitKey k => (k -> v -> v -> v) -> k -> v -> CritBit k v -> CritBit k vSource
O(k). Insert with a function, combining key, new value and old value.
will insert the pair (key, value) into cb if key does not exist in the map.
If the key does exist, the function will insert the pair
insertWithKey
f key value cb(key,f key new_value old_value)
.
Note that the key passed to f is the same key passed to insertWithKey.
let f key new_value old_value = byteCount key + new_value + old_value insertWithKey f "a" 1 (fromList [("a",5), ("b",3)]) == fromList [("a",7), ("b",3)] insertWithKey f "c" 1 (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3), ("c",1)] insertWithKey f "a" 1 empty == singleton "a" 1
insertLookupWithKey :: CritBitKey k => (k -> v -> v -> v) -> k -> v -> CritBit k v -> (Maybe v, CritBit k v)Source
O(k). Combines insert operation with old value retrieval.
The expression (
)
is a pair where the first element is equal to (insertLookupWithKey
f k x map
)
and the second element equal to (lookup
k map
).
insertWithKey
f k x map
let f key new_value old_value = length key + old_value + new_value insertLookupWithKey f "a" 2 (fromList [("a",5), ("b",3)]) == (Just 5, fromList [("a",8), ("b",3)]) insertLookupWithKey f "c" 2 (fromList [(5,"a"), (3,"b")]) == (Nothing, fromList [("a",5), ("b",3), ("c",2)]) insertLookupWithKey f "a" 2 empty == (Nothing, singleton "a" 2)
This is how to define insertLookup
using insertLookupWithKey
:
let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t insertLookup "a" 1 (fromList [("a",5), ("b",3)]) == (Just 5, fromList [("a",1), ("b",3)]) insertLookup "c" 1 (fromList [("a",5), ("b",3)]) == (Nothing, fromList [("a",5), ("b",3), ("c",1)])
Deletion
delete :: CritBitKey k => k -> CritBit k v -> CritBit k vSource
O(k). Delete a key and its value from the map. When the key is not a member of the map, the original map is returned.
delete "a" (fromList [("a",5), ("b",3)]) == singleton "b" 3 delete "c" (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3)] delete "a" empty == empty
adjust :: CritBitKey k => (v -> v) -> k -> CritBit k v -> CritBit k vSource
O(k). Update a value at a specific key with the result of the provided function. When the key is not a member of the map, the original map is returned.
let f k x = x + 1 adjustWithKey f "a" (fromList [("b",3), ("a",5)]) == fromList [("a", 6), ("b",3)] adjustWithKey f "c" (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3)] adjustWithKey f "c" empty == empty
adjustWithKey :: CritBitKey k => (k -> v -> v) -> k -> CritBit k v -> CritBit k vSource
O(k). Adjust a value at a specific key. When the key is not a member of the map, the original map is returned.
let f k x = x + fromEnum (k < "d") adjustWithKey f "a" (fromList [("b",3), ("a",5)]) == fromList [("a", 6), ("b",3)] adjustWithKey f "c" (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3)] adjustWithKey f "c" empty == empty
update :: CritBitKey k => (v -> Maybe v) -> k -> CritBit k v -> CritBit k vSource
O(k). The expression (
updates the value update
f k mapx
at k
(if it is in the map). If (f x
) is Nothing
, the element is
deleted. If it is (
), the key Just
yk
is bound to the new value y
.
let f x = if x == 5 then Just 50 else Nothing update f "a" (fromList [("b",3), ("a",5)]) == fromList [("a", 50), ("b",3)] update f "c" (fromList [("b",3), ("a",5)]) == fromList [("a", 50), ("b",3)] update f "b" (fromList [("b",3), ("a",5)]) == singleton "a" 5
updateWithKey :: CritBitKey k => (k -> v -> Maybe v) -> k -> CritBit k v -> CritBit k vSource
O(log n). The expression (
) updates the
value updateWithKey
f k mapx
at k
(if it is in the map). If (f k x
) is Nothing
,
the element is deleted. If it is (
), the key Just
yk
is bound
to the new value y
.
let f k x = if x == 5 then Just (x + fromEnum (k < "d")) else Nothing updateWithKey f "a" (fromList [("b",3), ("a",5)]) == fromList [("a", 6), ("b",3)] updateWithKey f "c" (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3)] updateWithKey f "b" (fromList [("a",5), ("b",3)]) == singleton "a" 5
updateLookupWithKey :: CritBitKey k => (k -> v -> Maybe v) -> k -> CritBit k v -> (Maybe v, CritBit k v)Source
O(k). Lookup and update; see also updateWithKey
.
This function returns the changed value if it is updated, or
the original value if the entry is deleted.
let f k x = if x == 5 then Just (x + fromEnum (k < "d")) else Nothing updateLookupWithKey f "a" (fromList [("b",3), ("a",5)]) == (Just 6, fromList [("a", 6), ("b",3)]) updateLookupWithKey f "c" (fromList [("a",5), ("b",3)]) == (Nothing, fromList [("a",5), ("b",3)]) updateLookupWithKey f "b" (fromList [("a",5), ("b",3)]) == (Just 3, singleton "a" 5)
alter :: CritBitKey k => (Maybe v -> Maybe v) -> k -> CritBit k v -> CritBit k vSource
O(k). The expression (
) alters the value alter
f k mapx
at k
, or absence thereof. alter
can be used to insert, delete,
or update a value in a CritBit
. In short :
.
lookup
k (alter
f k m) = f (lookup
k m)
let f _ = Nothing alter f "c" (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3)] alter f "a" (fromList [("a",5), ("b",3)]) == fromList [("b",3)] let f _ = Just 1 alter f "c" (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",3), ("c",1)] alter f "a" (fromList [(5,"a"), (3,"b")]) == fromList [("a",1), ("b",3)]
Combination
Union
unionWith :: CritBitKey k => (v -> v -> v) -> CritBit k v -> CritBit k v -> CritBit k vSource
Union with a combining function.
let l = fromList [("a", 5), ("b", 3)] let r = fromList [("A", 5), ("b", 7)] unionWith (+) l r == fromList [("A",5),("a",5),("b",10)]
unionWithKey :: CritBitKey k => (k -> v -> v -> v) -> CritBit k v -> CritBit k v -> CritBit k vSource
Union with a combining function.
let f key new_value old_value = byteCount key + new_value + old_value let l = fromList [("a", 5), ("b", 3)] let r = fromList [("A", 5), ("C", 7)] unionWithKey f l r == fromList [("A",5),("C",7),("a",5),("b",3)]
unions :: CritBitKey k => [CritBit k v] -> CritBit k vSource
The union of a list of maps:
(
).
unions
== foldl
union
empty
unions [(fromList [("a", 5), ("b", 3)]), (fromList [("a", 6), ("c", 7)]), (fromList [("a", 9), ("b", 5)])] == fromList [("a", 5), ("b", 4), (c, 7)] unions [(fromList [("a", 9), ("b", 8)]), (fromList [("ab", 5), ("c",7)]), (fromList [("a", 5), ("b", 3)])] == fromList [("a", 9), ("ab", 5), ("b", 8), ("c", 7)]
unionsWith :: CritBitKey k => (v -> v -> v) -> [CritBit k v] -> CritBit k vSource
The union of a list of maps, with a combining operation:
(
).
unionsWith
f == foldl
(unionWith
f) empty
unionsWith (+) [(fromList [("a",5), ("b", 3)]), (fromList [("a", 3), ("c", 7)]), (fromList [("a", 5), ("b", 5)])] == fromList [("a", 12), ("b", 8), ("c")]
Difference
difference :: CritBitKey k => CritBit k v -> CritBit k w -> CritBit k vSource
O(n+m). Difference of two maps. | Return data in the first map not existing in the second map.
let l = fromList [("a", 5), ("b", 3)] let r = fromList [("A", 2), ("b", 7)] difference l r == fromList [("a", 5)]
differenceWith :: CritBitKey k => (v -> w -> Maybe v) -> CritBit k v -> CritBit k w -> CritBit k vSource
O(n+m). Difference with a combining function.
| When two equal keys are encountered, the combining function is applied
| to the values of theese keys. If it returns Nothing
, the element is
| discarded (proper set difference). If it returns (
),
| the element is updated with a new value Just
yy
.
let f av bv = if av == 3 then Just (av + bv) else Nothing let l = fromList [(pack "a", 5), (pack "b", 3), (pack "c", 8)] let r = fromList [(pack "a", 2), (pack "b", 7), (pack "d", 8)] differenceWith f l r == fromList [(pack "b", 10), (pack "c", 8)]
differenceWithKey :: CritBitKey k => (k -> v -> w -> Maybe v) -> CritBit k v -> CritBit k w -> CritBit k vSource
O(n+m). Difference with a combining function.
| When two equal keys are encountered, the combining function is applied
| to the key and both values. If it returns Nothing
, the element is
| discarded (proper set difference). If it returns (
),
| the element is updated with a new value Just
yy
.
let f k av bv = if k == "b" then Just (length k + av + bv) else Nothing let l = fromList [("a", 5), ("b", 3), ("c", 8)] let r = fromList [("a", 2), ("b", 7), ("d", 8)] differenceWithKey f l r == fromList [("b", 11), ("c", 8)]
Intersection
intersection :: CritBitKey k => CritBit k v -> CritBit k w -> CritBit k vSource
O(n+m). Intersection of two maps. | Return data in the first map for the keys existing in both maps.
let l = fromList [("a", 5), ("b", 3)] let r = fromList [("A", 2), ("b", 7)] intersection l r == fromList [("b", 3)]
intersectionWith :: CritBitKey k => (v -> w -> x) -> CritBit k v -> CritBit k w -> CritBit k xSource
O(n+m). Intersection with a combining function.
let l = fromList [("a", 5), ("b", 3)] let r = fromList [("A", 2), ("b", 7)] intersectionWith (+) l r == fromList [("b", 10)]
intersectionWithKey :: CritBitKey k => (k -> v -> w -> x) -> CritBit k v -> CritBit k w -> CritBit k xSource
O(n+m). Intersection with a combining function.
let f key new_value old_value = length key + new_value + old_value let l = fromList [("a", 5), ("b", 3)] let r = fromList [("A", 2), ("b", 7)] intersectionWithKey f l r == fromList [("b", 11)]
Traversal
Map
map :: CritBitKey k => (v -> w) -> CritBit k v -> CritBit k wSource
O(n). Apply a function to all values.
map show (fromList [("b",5), ("a",3)]) == fromList [("b","5"), ("a","3")]
mapWithKey :: (k -> v -> w) -> CritBit k v -> CritBit k wSource
O(n). Apply a function to all values.
let f key x = show key ++ ":" ++ show x mapWithKey f (fromList [("a",5), ("b",3)]) == fromList [("a","a:5"), ("b","b:3")]
traverseWithKey :: (CritBitKey k, Applicative t) => (k -> v -> t w) -> CritBit k v -> t (CritBit k w)Source
O(n).
traverseWithKey
f s == fromList
$ traverse
((k, v) -> (,) k $ f k v) (toList
m)
That is, behaves exactly like a regular traverse
except
that the traversing function also has access to the key associated
with a value.
let f key value = show key ++ ":" ++ show value traverseWithKey (\k v -> if odd v then Just (f k v) else Nothing) (fromList [("a",3), ("b",5)]) == Just (fromList [("a","a:3"), ("b","b:5")]) traverseWithKey (\k v -> if odd v then Just (f k v) else Nothing) (fromList [("c", 2)]) == Nothing
mapAccum :: CritBitKey k => (a -> v -> (a, w)) -> a -> CritBit k v -> (a, CritBit k w)Source
O(n). The function mapAccum
threads an accumulating
argument through the map in ascending order of keys.
let f a b = (a ++ show b, show b ++ "X") mapAccum f "Everything: " (fromList [("a",5), ("b",3)]) == ("Everything: 53", fromList [("a","5X"), ("b","3X")])
mapAccumWithKey :: CritBitKey k => (a -> k -> v -> (a, w)) -> a -> CritBit k v -> (a, CritBit k w)Source
O(n). The function mapAccumWithKey
threads an accumulating
argument through the map in ascending order of keys.
let f a k b = (a ++ " " ++ show k ++ "-" ++ show b, show b ++ "X") mapAccumWithKey f "Everything: " (fromList [("a",5), ("b",3)]) == ("Everything: a-5 b-3", fromList [("a","5X"), ("b","3X")])
mapAccumRWithKey :: CritBitKey k => (a -> k -> v -> (a, w)) -> a -> CritBit k v -> (a, CritBit k w)Source
O(n). The function mapAccumRWithKey
threads an accumulating
argument through the map in descending order of keys.
mapKeys :: CritBitKey k2 => (k1 -> k2) -> CritBit k1 v -> CritBit k2 vSource
O(k).
mapKeys f
applies the function f
to the keys of the map.
If f
maps multiple keys to the same new key, the new key is
associated with the value of the greatest of the original keys.
let f = fromString . (++ "1") . show mapKeys f (fromList [("a", 5), ("b", 3)]) == fromList ([("a1", 5), ("b1", 3)]) mapKeys (\ _ -> "a") (fromList [("a", 5), ("b", 3)]) == singleton "a" 3
mapKeysWith :: CritBitKey k2 => (v -> v -> v) -> (k1 -> k2) -> CritBit k1 v -> CritBit k2 vSource
O(k).
is the map obtained by applying mapKeysWith
c f sf
to each key of s
.
The size of the result may be smaller if f
maps two or more distinct
keys to the same new key. In this case the associated values will be
combined using c
.
mapKeysWith (+) (\ _ -> "a") (fromList [("b",1), ("a",2), ("d",3), ("c",4)]) == singleton "a" 10
mapKeysMonotonic :: CritBitKey k => (a -> k) -> CritBit a v -> CritBit k vSource
O(k).
, but works only when mapKeysMonotonic
f s == mapKeys
f sf
is strictly monotonic.
That is, for any values x
and y
, if x
< y
then f x
< f y
.
The precondition is not checked.
Semi-formally, we have:
and [x < y ==> f x < f y | x <- ls, y <- ls] ==> mapKeysMonotonic f s == mapKeys f s where ls = keys s
This means that f
maps distinct original keys to distinct resulting keys.
This function has slightly better performance than mapKeys
.
mapKeysMonotonic (\ k -> succ k) (fromList [("a",5), ("b",3)]) == fromList [("b",5), ("c",3)]
Folds
foldlWithKey :: (a -> k -> v -> a) -> a -> CritBit k v -> aSource
O(n). Fold the keys and values in the map using the given
left-associative function, such that
.
foldlWithKey
f z == foldl
(\z' (kx, x) -> f z' kx x) z . toAscList
Examples:
keys = reverse . foldlWithKey (\ks k x -> k:ks) []
let f result k a = result ++ "(" ++ show k ++ ":" ++ a ++ ")" foldlWithKey f "Map: " (fromList [("a",5), ("b",3)]) == "Map: (b:3)(a:5)"
foldrWithKey :: (k -> v -> a -> a) -> a -> CritBit k v -> aSource
O(n). Fold the keys and values in the map using the given
right-associative function, such that
.
foldrWithKey
f z == foldr
(uncurry
f) z . toAscList
Examples:
keys map = foldrWithKey (\k x ks -> k:ks) [] map
let f k a result = result ++ "(" ++ show k ++ ":" ++ a ++ ")" foldrWithKey f "Map: " (fromList [("a",5), ("b",3)]) == "Map: (a:5)(b:3)"
Strict folds
foldl' :: (a -> v -> a) -> a -> CritBit k v -> aSource
O(n). A strict version of foldl
. Each application of the
function is evaluated before using the result in the next
application. This function is strict in the starting value.
foldr' :: (v -> a -> a) -> a -> CritBit k v -> aSource
O(n). A strict version of foldr
. Each application of the
function is evaluated before using the result in the next
application. This function is strict in the starting value.
foldlWithKey' :: (a -> k -> v -> a) -> a -> CritBit k v -> aSource
O(n). A strict version of foldlWithKey
. Each application of
the function is evaluated before using the result in the next
application. This function is strict in the starting value.
foldrWithKey' :: (k -> v -> a -> a) -> a -> CritBit k v -> aSource
O(n). A strict version of foldrWithKey
. Each application of
the function is evaluated before using the result in the next
application. This function is strict in the starting value.
Conversion
elems :: CritBit k v -> [v]Source
O(n). Return all the elements of the map in ascending order of their keys.
elems (fromList [("b",5), ("a",3)]) == [3,5] elems empty == []
keys :: CritBit k v -> [k]Source
O(n). Return all keys of the map in ascending order.
keys (fromList [("b",5), ("a",3)]) == ["a","b"] keys empty == []
assocs :: CritBit k v -> [(k, v)]Source
O(n). An alias for toAscList
. Return all key/value pairs in the map in
ascending order.
assocs (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")] assocs empty == []
keysSet :: CritBit k v -> Set kSource
O(n). Return set of all keys of the map.
keysSet (fromList [("b",5), ("a",3)]) == Set.fromList ["a", "b"] keysSet empty == []
fromSet :: (k -> v) -> Set k -> CritBit k vSource
O(n). Build a map from a set of keys and a function which for each key computes its value.
fromSet (\k -> length k) (Data.IntSet.fromList ["a", "bb"]) == fromList [("a",1), ("bb",2)] fromSet undefined Data.IntSet.empty == empty
Lists
toList :: CritBit k v -> [(k, v)]Source
O(n). Convert the map to a list of key/value pairs. The list returned will be sorted in lexicographically ascending order.
toList (fromList [("b",3), ("a",5)]) == [("a",5),("b",3)] toList empty == []
fromList :: CritBitKey k => [(k, v)] -> CritBit k vSource
O(k). Build a map from a list of key/value pairs. If the list contains more than one value for the same key, the last value for the key is retained.
fromList [] == empty fromList [("a",5), ("b",3), ("a",2)] == fromList [("a",2), ("b",3)]
fromListWith :: CritBitKey k => (v -> v -> v) -> [(k, v)] -> CritBit k vSource
O(k). Build a map from a list of key/value pairs
with a combining function. See also fromAscListWith
.
fromListWith (+) [("a",5), ("b",5), ("b",3), ("a",3), ("a",5)] == fromList [("a",13), ("b",8)] fromListWith (+) [] == empty
fromListWithKey :: CritBitKey k => (k -> v -> v -> v) -> [(k, v)] -> CritBit k vSource
O(k). Build a map from a list of key/value pairs
with a combining function. See also fromAscListWithKey
.
let f key a1 a2 = byteCount key + a1 + a2 fromListWithKey f [("a",5), ("b",5), ("b",3), ("a",3), ("a",5)] == fromList [("a",16), ("b",10)] fromListWithKey f [] == empty
Ordered lists
toAscList :: CritBit k v -> [(k, v)]Source
O(n). Convert the map to a list of key/value pairs where the keys are in ascending order.
toAscList (fromList [(5,"a"), (3,"b")]) == [(3,"b"), (5,"a")]
toDescList :: CritBit k v -> [(k, v)]Source
O(n). Convert the map to a list of key/value pairs where the keys are in descending order.
toDescList (fromList [(5,"a"), (3,"b")]) == [(5,"a"), (3,"b")]
fromAscList :: CritBitKey k => [(k, a)] -> CritBit k aSource
O(n). Build a tree from an ascending list in linear time. The precondition (input list is ascending) is not checked.
fromAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")] fromAscList [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "b")] valid (fromAscList [(3,"b"), (5,"a"), (5,"b")]) == True valid (fromAscList [(5,"a"), (3,"b"), (5,"b")]) == False
fromAscListWith :: CritBitKey k => (a -> a -> a) -> [(k, a)] -> CritBit k aSource
O(n). Build a tree from an ascending list in linear time with a combining function for equal keys. The precondition (input list is ascending) is not checked.
fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")] valid (fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")]) == True valid (fromAscListWith (++) [(5,"a"), (3,"b"), (5,"b")]) == False
fromAscListWithKey :: CritBitKey k => (k -> a -> a -> a) -> [(k, a)] -> CritBit k aSource
O(n). Build a map from an ascending list in linear time with a combining function for equal keys. The precondition (input list is ascending) is not checked.
let f k a1 a2 = (show k) ++ ":" ++ a1 ++ a2 fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")] == fromList [(3, "b"), (5, "5:b5:ba")] valid (fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b"), (5,"b")]) == True valid (fromAscListWithKey f [(5,"a"), (3,"b"), (5,"b"), (5,"b")]) == False
fromDistinctAscList :: CritBitKey k => [(k, a)] -> CritBit k aSource
O(n). Build a tree from an ascending list of distinct elements in linear time. The precondition is not checked.
fromDistinctAscList [(3,"b"), (5,"a")] == fromList [(3, "b"), (5, "a")] valid (fromDistinctAscList [(3,"b"), (5,"a")]) == True valid (fromDistinctAscList [(3,"b"), (5,"a"), (5,"b")]) == False
Filter
filter :: (v -> Bool) -> CritBit k v -> CritBit k vSource
O(n). Filter all values that satisfy the predicate.
filter (> "a") (fromList [("5","a"), ("3","b")]) == fromList [("3","b")] filter (> "x") (fromList [("5","a"), ("3","b")]) == empty filter (< "a") (fromList [("5","a"), ("3","b")]) == empty
filterWithKey :: (k -> v -> Bool) -> CritBit k v -> CritBit k vSource
O(n). Filter all keys/values that satisfy the predicate.
filterWithKey (\k _ -> k > "4") (fromList [("5","a"), ("3","b")]) == fromList[("5","a")]
partition :: CritBitKey k => (v -> Bool) -> CritBit k v -> (CritBit k v, CritBit k v)Source
O(n). Partition the map according to a predicate. The first
map contains all elements that satisfy the predicate, the second all
elements that fail the predicate. See also split
.
partition (> 4) (fromList [("a",5), ("b",3)]) == (fromList [("a",5)], fromList [("b",3)]) partition (< 6) (fromList [("a",5), ("b",3)]) == (fromList [("a",5), ("b",3)], empty) partition (> 6) (fromList [("a",5), ("b",3)]) == (empty, fromList [("a",5), ("b",3)])
partitionWithKey :: CritBitKey k => (k -> v -> Bool) -> CritBit k v -> (CritBit k v, CritBit k v)Source
O(n). Partition the map according to a predicate. The first
map contains all elements that satisfy the predicate, the second all
elements that fail the predicate. See also split
.
partitionWithKey (\ k _ -> k < "b") (fromList [("a",5), ("b",3)]) == (fromList [("a",5)], fromList [("b",3)]) partitionWithKey (\ k _ -> k < "c") (fromList [(5,"a"), (3,"b")]) == (fromList [("a",5), ("b",3)], empty) partitionWithKey (\ k _ -> k > "c") (fromList [(5,"a"), (3,"b")]) == (empty, fromList [("a",5), ("b",3)])
mapMaybe :: (a -> Maybe b) -> CritBit k a -> CritBit k bSource
O(n). Map values and collect the Just
results.
let f x = if x == 5 then Just 10 else Nothing mapMaybe f (fromList [("a",5), ("b",3)]) == singleton "a" 10
mapMaybeWithKey :: (k -> v -> Maybe v') -> CritBit k v -> CritBit k v'Source
O(n). Map keys/values and collect the Just
results.
let f k v = if k == "a" then Just ("k,v: " ++ show k ++ "," ++ show v) else Nothing mapMaybeWithKey f (fromList [("a",5), ("b",3)]) == singleton "a" "k,v: \"a\",3"
mapEither :: (a -> Either b c) -> CritBit k a -> (CritBit k b, CritBit k c)Source
O(n). Map values and separate the Left
and Right
results.
let f a = if a < 5 then Left a else Right a mapEither f (fromList [("a",5), ("b",3), ("x",1), ("z",7)]) == (fromList [("b",3), ("x",1)], fromList [("a",5), ("z",7)]) mapEither (\ a -> Right a) (fromList [("a",5), ("b",3), ("x",1), ("z",7)]) == (empty, fromList [("a",5), ("b",3), ("x",1), ("z",7)])
mapEitherWithKey :: (k -> v -> Either v1 v2) -> CritBit k v -> (CritBit k v1, CritBit k v2)Source
O(n). Map keys/values and separate the Left
and Right
results.
let f k a = if k < "c" then Left (k ++ k) else Right (a * 2) mapEitherWithKey f (fromList [("a",5), ("b",3), ("x",1), ("z",7)]) == (fromList [("a","aa"), ("b","bb")], fromList [("x",2), ("z",14)]) mapEitherWithKey (\_ a -> Right a) (fromList [("a",5), ("b",3), ("x",1), ("z",7)]) == (empty, fromList [("x",1), ("b",3), ("a",5), ("z",7)])
split :: CritBitKey k => k -> CritBit k v -> (CritBit k v, CritBit k v)Source
O(k). The expression (
) is a pair
split
k map(map1,map2)
where the keys in map1
are smaller than k
and the
keys in map2
larger than k
. Any key equal to k
is found in
neither map1
nor map2
.
split "a" (fromList [("b",1), ("d",2)]) == (empty, fromList [("b",1), ("d",2)]) split "b" (fromList [("b",1), ("d",2)]) == (empty, singleton "d" 2) split "c" (fromList [("b",1), ("d",2)]) == (singleton "b" 1, singleton "d" 2) split "d" (fromList [("b",1), ("d",2)]) == (singleton "b" 1, empty) split "e" (fromList [("b",1), ("d",2)]) == (fromList [("b",1), ("d",2)], empty)
splitLookup :: CritBitKey k => k -> CritBit k v -> (CritBit k v, Maybe v, CritBit k v)Source
O(k). The expression (
) splits a map just
like splitLookup
k mapsplit
but also returns
.
lookup
k map
splitLookup "a" (fromList [("b",1), ("d",2)]) == (empty, Nothing, fromList [("b",1), ("d",2)]) splitLookup "b" (fromList [("b",1), ("d",2)]) == (empty, Just 1, singleton "d" 2) splitLookup "c" (fromList [("b",1), ("d",2)]) == (singleton "b" 1, Nothing, singleton "d" 2) splitLookup "d" (fromList [("b",1), ("d",2)]) == (singleton "b" 1, Just 2, empty) splitLookup "e" (fromList [("b",1), ("d",2)]) == (fromList [("b",1), ("d",2)], Nothing, empty)
Submap
isSubmapOf :: (CritBitKey k, Eq v) => CritBit k v -> CritBit k v -> BoolSource
O(n+m). This function is defined as
(
).
isSubmapOf
= isSubmapOfBy
(==)
isSubmapOfBy :: CritBitKey k => (a -> b -> Bool) -> CritBit k a -> CritBit k b -> BoolSource
O(n+m). The expression (
) returns isSubmapOfBy
f t1 t2True
if
all keys in t1
are in map t2
, and when f
returns True
when
applied to their respective values. For example, the following
expressions are all True
:
isSubmapOfBy (==) (fromList [("a",1)]) (fromList [("a",1),("b",2)]) isSubmapOfBy (<=) (fromList [("a",1)]) (fromList [("a",1),("b",2)]) isSubmapOfBy (==) (fromList [("a",1),("b",2)]) (fromList [("a",1),("b",2)])
But the following are all False
:
isSubmapOfBy (==) (fromList [("a",2)]) (fromList [("a",1),("b",2)]) isSubmapOfBy (<) (fromList [("a",1)]) (fromList [("a",1),("b",2)]) isSubmapOfBy (==) (fromList [("a",1),("b",2)]) (fromList [("a",1)])
isProperSubmapOf :: (CritBitKey k, Eq v) => CritBit k v -> CritBit k v -> BoolSource
O(n+m). Is this a proper submap? (ie. a submap but not equal).
Defined as (
).
isProperSubmapOf
= isProperSubmapOfBy
(==)
isProperSubmapOfBy :: CritBitKey k => (a -> b -> Bool) -> CritBit k a -> CritBit k b -> BoolSource
O(n+m). Is this a proper submap? (ie. a submap but not equal).
The expression (
) returns isProperSubmapOfBy
f m1 m2True
when
m1
and m2
are not equal,
all keys in m1
are in m2
, and when f
returns True
when
applied to their respective values. For example, the following
expressions are all True
:
isProperSubmapOfBy (==) (fromList [("a",1)]) (fromList [("a",1),("b",2)]) isProperSubmapOfBy (<=) (fromList [("a",0)]) (fromList [("a",1),("b",2)])
But the following are all False
:
isProperSubmapOfBy (==) (fromList [("a",1),("b",2)]) (fromList [("a",1),("b",2)]) isProperSubmapOfBy (==) (fromList ["a",1),("b",2)]) (fromList [("a",1)]) isProperSubmapOfBy (<) (fromList [("a",1)]) (fromList [("a",1),("b",2)])
findMin :: CritBit k v -> (k, v)Source
O(minimum K). The minimal key of the map. Calls error
if the map
is empty.
findMin (fromList [("b",3), ("a",5)]) == ("a",5) findMin empty Error: empty map has no minimal element
findMax :: CritBit k v -> (k, v)Source
O(k). The maximal key of the map. Calls error
if the map
is empty.
findMax empty Error: empty map has no minimal element
deleteMin :: CritBit k v -> CritBit k vSource
O(k'). Delete the minimal key. Returns an empty map if the map is empty.
deleteMin (fromList [("a",5), ("b",3), ("c",7)]) == fromList [("b",3), ("c",7)] deleteMin empty == empty
deleteMax :: CritBit k v -> CritBit k vSource
O(k). Delete the maximal key. Returns an empty map if the map is empty.
deleteMin (fromList [("a",5), ("b",3), ("c",7)]) == fromList [("a",5), ("b","3")] deleteMin empty == empty
deleteFindMin :: CritBit k v -> ((k, v), CritBit k v)Source
O(k'). Delete and find the minimal element.
deleteFindMin (fromList [("a",5), ("b",3), ("c",10)]) == (("a",5), fromList[("b",3), ("c",10)]) deleteFindMin Error: can not return the minimal element of an empty map
deleteFindMax :: CritBit k v -> ((k, v), CritBit k v)Source
O(k). Delete and find the maximal element.
deleteFindMax (fromList [("a",5), ("b",3), ("c",10)]) == (("c",10), fromList[("a",5), ("b",3)]) deleteFindMax Error: can not return the maximal element of an empty map
updateMin :: (v -> Maybe v) -> CritBit k v -> CritBit k vSource
O(k'). Update the value at the minimal key.
updateMin (\ a -> Just (a + 7)) (fromList [("a",5), ("b",3)]) == fromList [("a",12), ("b",3)] updateMin (\ _ -> Nothing) (fromList [("a",5), ("b",3)]) == fromList [("b",3)]
updateMax :: (v -> Maybe v) -> CritBit k v -> CritBit k vSource
O(k). Update the value at the maximal key.
updateMax (\ a -> Just (a + 7)) (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",10)] updateMax (\ _ -> Nothing) (fromList [("a",5), ("b",3)]) == fromList [("a",5)]
updateMinWithKey :: (k -> v -> Maybe v) -> CritBit k v -> CritBit k vSource
O(k'). Update the value at the minimal key.
updateMinWithKey (\ k a -> Just (length k + a)) (fromList [("a",5), ("b",3)]) == fromList [("a",6), ("b",3)] updateMinWithKey (\ _ _ -> Nothing) (fromList [("a",5), ("b",3)]) == fromList [("b",3)]
updateMaxWithKey :: (k -> v -> Maybe v) -> CritBit k v -> CritBit k vSource
O(k). Update the value at the maximal key.
updateMaxWithKey (\ k a -> Just (length k + a)) (fromList [("a",5), ("b",3)]) == fromList [("a",5), ("b",4)] updateMaxWithKey (\ _ _ -> Nothing) (fromList [("a",5), ("b",3)]) == fromList [("a",5)]
minView :: CritBit k v -> Maybe (v, CritBit k v)Source
O(k'). Retrieves the value associated with minimal key of the
map, and the map stripped of that element, or Nothing
if passed an
empty map.
minView (fromList [("a",5), ("b",3)]) == Just (5, fromList [("b",3)]) minView empty == Nothing
maxView :: CritBit k v -> Maybe (v, CritBit k v)Source
O(k). Retrieves the value associated with maximal key of the
map, and the map stripped of that element, or Nothing
if passed an
empty map.
maxView (fromList [("a",5), ("b",3)]) == Just (3, fromList [("a",5)]) maxView empty == Nothing
minViewWithKey :: CritBit k v -> Maybe ((k, v), CritBit k v)Source
O(k'). Retrieves the minimal (key,value) pair of the map, and
the map stripped of that element, or Nothing
if passed an empty map.
minViewWithKey (fromList [("a",5), ("b",3)]) == Just (("a",5), fromList [("b",3)]) minViewWithKey empty == Nothing
maxViewWithKey :: CritBit k v -> Maybe ((k, v), CritBit k v)Source
O(k). Retrieves the maximal (key,value) pair of the map, and
the map stripped of that element, or Nothing
if passed an empty map.
maxViewWithKey (fromList [("a",5), ("b",3)]) == Just (("b",3), fromList [("a",5)]) maxViewWithKey empty == Nothing