This module provides functions to manipulate dictionaries or hash maps in a more efficient way than association lists.
Note: Data.Map is the same as Data.Map.Lazy
Example:
>>> import qualified Data.Map as Map
>>>
let alist = [(10, "Texas"), (2, "Utah"), (3, "New Mexico"), (14, "Ohio")]
>>> :t Map.fromList
Map.fromList :: Ord k => [(k, a)] -> M.Map k a
>>>
>>> :t hmap1
hmap1 :: (Num k, Ord k) => M.Map k [Char]
>>> hmap1
fromList [(2,"Utah"),(3,"New Mexico"),(10,"Texas"),(14,"Ohio")]
>>>
>>>
-- member :: Ord k => k -> Map k a -> Bool
--
-- Test if a key is a member of the map.
>>> :t Map.member
Map.member :: Ord k => k -> M.Map k a -> Bool
>>>
>>> Map.member 2 hmap1
True
>>> Map.member 20 hmap1
False
>>>
-- notMember :: Ord k => k -> Map k a -> Bool
--
--
-- Test if a key is a not a member of the map.
>>> Map.notMember 20 hmap1
True
>>> Map.notMember 2 hmap1
False
>>>
{- lookup :: Ord k => k -> Map k a -> Maybe a
Lookup the value at a key in the map.
The function will return the corresponding value as (Just value), or Nothing if the key
isn't in the map.
-}
>>> :t Map.lookup
Map.lookup :: Ord k => k -> M.Map k a -> Maybe a
>>>
>>> Map.lookup 1 hmap1
Nothing
>>> Map.lookup 14 hmap1
Just "Ohio"
>>> Map.lookup 10 hmap1
Just "Texas"
>>> Map.lookup 30 hmap1
Nothing
>>>
>>> Map.keys hmap1
[2,3,10,14]
>>>
-- A insertion in the Map doesn't change it. It creates a new
-- one updated from the the old Map.
--
>>> Map.insert 1 "Virginia" hmap1
fromList [(1,"Virginia"),(2,"Utah"),(3,"New Mexico"),(10,"Texas"),(14,"Ohio")]
>>>
>>> hmap1
fromList [(2,"Utah"),(3,"New Mexico"),(10,"Texas"),(14,"Ohio")]
>>>
--- The expression (findWithDefault def k map) returns the value at
--- key k or returns default value def when the key is not in the
--- map.
---
>>> :t Map.findWithDefault
Map.findWithDefault :: Ord k => a -> k -> M.Map k a -> a
>>>
>>> Map.findWithDefault "Arizona" 2 hmap1
"Utah"
>>> Map.findWithDefault "Arizona" 20 hmap1
"Arizona"
>>> Map.findWithDefault "Arizona" 30 hmap1
"Arizona"
>>>
--- Empty map
---
>>> Map.empty
fromList []
>>>
-- Map with single element
---
---
>>> :t Map.singleton
Map.singleton :: k -> a -> M.Map k a
>>>
>>> Map.singleton "Texas" 30
fromList [("Texas",30)]
>>>
{-
Insert with a function, combining new value and old value. insertWith f
key value mp will insert the pair (key, value) into mp 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).
-}
>>> let hmap = Map.fromList [("a", 3), ("x", 2), ("c", 10), ("m", 23)]
>>> hmap
fromList [("a",3),("c",10),("m",23),("x",2)]
>>>
>>> Map.insertWith (\new old -> 10 * old + new) "c" 3 hmap
fromList [("a",3),("c",103),("m",23),("x",2)]
>>>
>>> Map.insertWith (\new old -> 10 * old + new) "a" 5 hmap
fromList [("a",35),("c",10),("m",23),("x",2)]
>>> Map.insertWith (\new old -> 10 * old + new) "sad" 5 hmap
fromList [("a",3),("c",10),("m",23),("sad",5),("x",2)]
>>>
{-
Delete a key and its value from the map.
When the key is not a member of the map, the original map
is returned. (Non descructive update).
-}
let hmap = Map.fromList [("a", 3), ("x", 2), ("c", 10), ("m", 23)]
>>> hmap
fromList [("a",3),("c",10),("m",23),("x",2)]
>>>
>>> :t Map.delete
Map.delete :: Ord k => k -> M.Map k a -> M.Map k a
>>>
>>> Map.delete "a" hmap
fromList [("c",10),("m",23),("x",2)]
>>> Map.delete "z" hmap
fromList [("a",3),("c",10),("m",23),("x",2)]
>>>
-- Non destructive deletion.
--
>>> hmap
fromList [("a",3),("c",10),("m",23),("x",2)]
>>>
>>> Map.delete "x" $ Map.delete "m" $ Map.delete "c" $ Map.delete "a" hmap
fromList []
>>>
>>> Map.delete "x" $ Map.empty
fromList []
>>>
{- adjust :: Ord k => (a -> a) -> k -> Map k a -> Map k a
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.
-}
>>> :t Map.adjust
Map.adjust :: Ord k => (a -> a) -> k -> M.Map k a -> M.Map k a
>>>
>>> hmap
fromList [("a",3),("c",10),("m",23),("x",2)]
>>>
>>> Map.adjust (\x -> x * 10) "a" hmap
fromList [("a",30),("c",10),("m",23),("x",2)]
>>>
>>> Map.adjust (\x -> 0) "x" hmap
fromList [("a",3),("c",10),("m",23),("x",0)]
>>>
>>> Map.adjust (\x -> 0) "wrong" hmap
fromList [("a",3),("c",10),("m",23),("x",2)]
>>>
>>> Map.adjust (\x -> 0) "wrong" Map.empty
fromList []
>>>
{- Adjust a value at a specific key. When the key is not a member of
the map, the original map is returned.
-}
>>> :t Map.adjustWithKey
Map.adjustWithKey
:: Ord k => (k -> a -> a) -> k -> M.Map k a -> M.Map k a
>>>
>>> let hm = Map.fromList [(12, "23"), (2, "c"), (4, "k")]
>>> hm
fromList [(2,"c"),(4,"k"),(12,"23")]
>>>
>>> Map.adjustWithKey (\k a -> show $ length a + k) 4 hm
fromList [(2,"c"),(4,"5"),(12,"23")]
>>> Map.adjustWithKey (\k a -> show $ length a + k) 12 hm
fromList [(2,"c"),(4,"k"),(12,"14")]
>>> Map.adjustWithKey (\k a -> show $ length a + k) 123 hm
fromList [(2,"c"),(4,"k"),(12,"23")]
>>>
{-
The expression (update f k map) updates the value x at k (if it is
in the map). If (f x) is Nothing, the element is deleted. If it is
(Just y), the key k is bound to the new value
-}
>>> :t Map.update
Map.update
:: Ord k => (a -> Maybe a) -> k -> M.Map k a -> M.Map k a
>>>
>>>
>>> let hm = Map.fromList [(12, "23"), (2, "c"), (4, "k")]
>>> Map.update (\x -> if x == "c" then Just "f" else Nothing) 2 hm
fromList [(2,"f"),(4,"k"),(12,"23")]
>>>
>>> Map.update (\x -> if x == "c" then Just "f" else Nothing) 20 hm
fromList [(2,"c"),(4,"k"),(12,"23")]
>>>
>>> Map.update (\x -> if x == "c" then Just "f" else Nothing) 4 hm
fromList [(2,"c"),(12,"23")]
>>> Map.update (\x -> if x == "c" then Just "f" else Just "m") 4 hm
fromList [(2,"c"),(4,"m"),(12,"23")]
>>>
{-
The expression (union t1 t2) takes the left-biased union of t1 and
t2. It prefers t1 when duplicate keys are encountered, i.e. (union ==
unionWith const). The implementation uses the efficient hedge-union
algorithm.
-}
>>> Map.union (Map.fromList [(5, "a"), (3, "b")]) (Map.fromList [(5, "a"), (7, "C"), (5, "a")])
fromList [(3,"b"),(5,"a"),(7,"C")]
>>>
>>> Map.fromList [(5, "a"), (3, "b")] `Map.union` Map.fromList [(5, "a"), (7, "C"), (5, "a")]
fromList [(3,"b"),(5,"a"),(7,"C")]
>>>
{- unions :: Ord k => [Map k a] -> Map k a
The union of a list of maps: (unions == foldl union empty).
-}
>>> :t Map.unions
Map.unions :: Ord k => [M.Map k a] -> M.Map k a
>>>
>>>
>>> let fromList = Map.fromList
>>> :t fromList
fromList :: Ord k => [(k, a)] -> M.Map k a
>>>
>>> Map.unions [fromList [(1, "a"), (2, "c")], fromList [(2, "c"), (3, "m")], fromList [(10, "x"), (3, "m"), (4, "y")] ]
fromList [(1,"a"),(2,"c"),(3,"m"),(4,"y"),(10,"x")]
>>>
{-
Difference of two maps. Return elements of the first map not existing
in the second map. The implementation uses an efficient hedge
algorithm comparable with hedge-union.
-}
>>> let fromList = Map.fromList
>>> Map.difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")])
fromList [(3,"b")]
>>>
{-
Intersection of two maps. Return data in the first map for the keys
existing in both maps. (intersection m1 m2 == intersectionWith const
m1 m2). The implementation uses an efficient hedge algorithm
comparable with hedge-union.
-}
>>> :t Map.intersection
Map.intersection :: Ord k => M.Map k a -> M.Map k b -> M.Map k a
>>>
>>> Map.intersection (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")])
fromList [(5,"a")]
>>>
>>> fromList [(5, "a"), (3, "b")] `Map.intersection` fromList [(5, "A"), (7, "C")]
fromList [(5,"a")]
>>>
{-
map :: (a -> b) -> Map k a -> Map k b
Source
O(n). Map a function over all values in the map.
-}
let hmap = Map.fromList [("a", 3), ("x", 2), ("c", 10), ("m", 23)]
>>> Map.map (\x -> x * 10) hmap
fromList [("a",30),("c",100),("m",230),("x",20)]
>>>
{-
mapAccum :: (a -> b -> (a, c)) -> a -> Map k b -> (a, Map k c)
The function mapAccum threads an accumulating argument through the map
in ascending order of keys.
-}
>>> :t Map.mapAccum
Map.mapAccum
:: (a -> b -> (a, c)) -> a -> M.Map k b -> (a, M.Map k c)
>>>
let hmap = Map.fromList [("a", 3), ("x", 2), ("c", 10), ("m", 23)]
-- acc -> Initial value of accumulator
-- val -> Value of hash map at a key k
--
--
>>> Map.mapAccum (\acc val -> (acc + val, 10 * val)) 0 hmap
(38,fromList [("a",30),("c",100),("m",230),("x",20)])
>>>
{- mapKeys :: Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
-}
let hmap = Map.fromList [("a", 3), ("x", 2), ("c", 10), ("m", 23)]
>>> import Data.Char (ord)
>>>
>>> :t ord
ord :: Char -> Int
>>>
>>> Map.mapKeys (map ord) hmap
fromList [([97],3),([99],10),([109],23),([120],2)]
>>>
>>> Map.mapKeys (\x -> x ++ "-z") hmap
fromList [("a-z",3),("c-z",10),("m-z",23),("x-z",2)]
>>>
{- Ge all values -}
>>> Map.elems hmap
[3,10,23,2]
>>>
{- Get all keys -}
>>> Map.keys hmap
["a","c","m","x"]
>>>
{- Convert from List -}
>>> Map.toList hmap
[("a",3),("c",10),("m",23),("x",2)]
>>>