Module: Data.Map

Table of Contents

1 Data.Map

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)]
>>>

Author: Caio Rodrigues Soares Silva

Created: 2018-05-07 Mon 10:10

Emacs 25.3.1 (Org mode 8.2.10)

Validate