Los diccionarios (también llamados listas de asociación) son listas utilizadas para almacenar pares clave-valor donde el orden no importa. Por ejemplo, podemos tener un diccionario para almacenar números de teléfono, donde los números de telefono serían los valores y los nombres de la gente serían las claves. No nos importa el orden en el que estén almacenados, sólo queremos obtener el número correspondiente cada persona.

En este manual se presentan ejemplos de las funciones de la librería de diccionarios Data.Map 0.5.5.1. En los ejemplos se supone que se han importado la siguiente librería

ghci> import Data.Map as M

1 El tipo de los diccionarios

ghci> let d1 = fromList [("Ana",5),("Juan",7),("Eva",6)]
ghci> :t d1
d1 :: Map [Char] Integer
ghci> let d2 = fromList [("Ana",5),("Eva",6),("Juan",7)]
ghci> d1 == d2
True

2 Construcción de diccionarios

2.1 Constructores básicos

ghci> empty
fromList []
ghci> singleton 'd' 4
fromList [('d',4)]

2.2 Inserción de elementos

ghci> insert 3 7 empty
fromList [(3,7)]
ghci> insert 3 'c' (fromList [(4,'a'),(6,'b'),(8,'e')])
fromList [(3,'c'),(4,'a'),(6,'b'),(8,'e')]
ghci> insert 6 'c' (fromList [(4,'a'),(6,'b'),(8,'e')])
fromList [(4,'a'),(6,'c'),(8,'e')]
ghci> insertWith (++) 7 "d" (fromList [(5,"a"), (3,"b")])
fromList [(3,"b"),(5,"a"),(7,"d")]
ghci> insertWith (++) 3 "d" (fromList [(5,"a"), (3,"b")])
fromList [(3,"db"),(5,"a")]
ghci> insertWith (*) 3 2 (fromList [(5,6), (3,4)])
fromList [(3,8),(5,6)]
ghci> insertWith (*) 3 2 empty
fromList [(3,2)]
ghci> let f k x y = y ++ concat (replicate k x)
ghci> insertWithKey f 7 "d" (fromList [(5,"a"), (3,"b")])
fromList [(3,"b"),(5,"a"),(7,"d")]
ghci> insertWithKey f 3 "m" (fromList [(5,"a"), (3,"b")])
fromList [(3,"bmmm"),(5,"a")]
ghci> let f k x y = y ++ concat (replicate k x)
ghci> insertLookupWithKey f 7 "m" (fromList [(5,"a"), (3,"b")])
(Nothing,fromList [(3,"b"),(5,"a"),(7,"m")])
ghci> insertLookupWithKey f 3 "m" (fromList [(5,"a"), (3,"b")])
(Just "b",fromList [(3,"bmmm"),(5,"a")])

2.3 Eliminación y actualización de elementos

ghci> delete 3 (fromList [(5,"a"),(3,"b"),(7,"d")])
fromList [(5,"a"),(7,"d")]
ghci> delete 4 (fromList [(5,"a"),(3,"b"),(7,"d")])
fromList [(3,"b"),(5,"a"),(7,"d")]
ghci> adjust (+2) 3 (fromList [(5,1),(3,6)])
fromList [(3,8),(5,1)]
ghci> adjust (+2) 4 (fromList [(5,1),(3,6)])
fromList [(3,6),(5,1)]
ghci> let f k x = k*x
ghci> adjustWithKey f 3 (fromList [(5,1),(3,6)])
fromList [(3,18),(5,1)]
ghci> adjustWithKey f 4 (fromList [(5,1),(3,6)])
fromList [(3,6),(5,1)]
ghci> adjustWithKey f 4 empty
fromList []
ghci> let f x = if odd x then Just (2*x) else Nothing
ghci> update f 4 (fromList [(3,2),(4,5)])
fromList [(3,2),(4,10)]
ghci> update f 3 (fromList [(3,2),(4,5)])
fromList [(4,5)]
ghci> update f 6 (fromList [(3,2),(4,5)])
fromList [(3,2),(4,5)]
ghci> let f k x = if odd x then Just (k*x) else Nothing
ghci> updateWithKey f 4 (fromList [(3,2),(4,5)])
fromList [(3,2),(4,20)]
ghci> updateWithKey f 3 (fromList [(3,2),(4,5)])
fromList [(4,5)]
ghci> updateWithKey f 6 (fromList [(3,2),(4,5)])
fromList [(3,2),(4,5)]
ghci> let f k x = if odd x then Just (k*x) else Nothing
ghci> updateLookupWithKey f 4 (fromList [(3,2),(4,5)])
(Just 20,fromList [(3,2),(4,20)])
ghci> updateLookupWithKey f 3 (fromList [(3,2),(4,5)])
(Just 2,fromList [(4,5)])
ghci> updateLookupWithKey f 6 (fromList [(3,2),(4,5)])
(Nothing,fromList [(3,2),(4,5)])
ghci> let f _ = Nothing
ghci> alter f 4 (fromList [(3,2),(4,5)])
fromList [(3,2)]
ghci> alter f 7 (fromList [(3,2),(4,5)])
fromList [(3,2),(4,5)]
ghci> let f _ = Just 9
ghci> alter f 4 (fromList [(3,2),(4,5)])
fromList [(3,2),(4,9)]
ghci> alter f 7 (fromList [(3,2),(4,5)])
fromList [(3,2),(4,5),(7,9)]

3 Información sobre diccionarios

ghci> M.null (fromList [])
True
ghci> M.null (fromList [(3,2)])
False
ghci> size empty
0
ghci> size (fromList [(4,'a'),(5,'b'),(2,'e')])
3
ghci> size (fromList [(4,'a'),(5,'b'),(2,'e'),(4,'a')])
3
ghci> size (fromList [(4,'a'),(5,'b'),(2,'e'),(4,'c')])
3
ghci> M.lookup 5 (fromList [(4,'a'),(5,'b'),(2,'e')])
Just 'b'
ghci> M.lookup 7 (fromList [(4,'a'),(5,'b'),(2,'e')])
Nothing
ghci> member 5 (fromList [(4,'a'),(5,'b'),(2,'e')])
True
ghci> member 7 (fromList [(4,'a'),(5,'b'),(2,'e')])
False
ghci> notMember 7 (fromList [(4,'a'),(5,'b'),(2,'e')])
True
ghci> notMember 5 (fromList [(4,'a'),(5,'b'),(2,'e')])
False
ghci> fromList [(4,'a'),(5,'b'),(2,'e')] ! 5
'b'
ghci> fromList [(4,'a'),(5,'b'),(2,'e')] ! 7
*** Exception: Map.!: given key is not an element in the map
ghci> findWithDefault 'p' 5 (fromList [(4,'a'),(5,'b'),(2,'e')])
'b'
ghci> findWithDefault 'p' 7 (fromList [(4,'a'),(5,'b'),(2,'e')])
'p'
ghci> lookupLT 3 (fromList [(4,'a'),(5,'b'),(2,'e')])
Just (2,'e')
ghci> lookupLT 2 (fromList [(4,'a'),(5,'b'),(2,'e')])
Nothing
ghci> lookupGT 4 (fromList [(4,'a'),(6,'b'),(8,'e')])
Just (6,'b')
ghci> lookupGT 9 (fromList [(4,'a'),(6,'b'),(8,'e')])
Nothing
ghci> lookupLE 3 (fromList [(4,'a'),(5,'b'),(2,'e')])
Just (2,'e')
ghci> lookupLE 2 (fromList [(4,'a'),(5,'b'),(2,'e')])
Just (2,'e')
ghci> lookupLE 1 (fromList [(4,'a'),(5,'b'),(2,'e')])
Nothing
ghci> lookupGE 4 (fromList [(4,'a'),(6,'b'),(8,'e')])
Just (4,'a')
ghci> lookupGE 8 (fromList [(4,'a'),(6,'b'),(8,'e')])
Just (8,'e')
ghci> lookupGE 9 (fromList [(4,'a'),(6,'b'),(8,'e')])
Nothing

4 Índices

ghci> findIndex 3 (fromList [(5,"a"), (3,"b")])
0
ghci> findIndex 5 (fromList [(5,"a"), (3,"b")])
1
ghci> findIndex 7 (fromList [(5,"a"), (3,"b")])
*** Exception: Map.findIndex: element is not in the map
ghci> lookupIndex 3 (fromList [(5,"a"), (3,"b")])
Just 0
ghci> lookupIndex 5 (fromList [(5,"a"), (3,"b")])
Just 1
ghci> lookupIndex 7 (fromList [(5,"a"), (3,"b")])
Nothing
ghci> elemAt 0 (fromList [(5,"a"), (3,"b")])
(3,"b")
ghci> elemAt 1 (fromList [(5,"a"), (3,"b")])
(5,"a")
ghci> elemAt 2 (fromList [(5,"a"), (3,"b")])
*** Exception: Map.elemAt: index out of range
ghci> let f k x = if odd x then Just (k*x) else Nothing
ghci> updateAt f 0 (fromList [(5,4), (3,1)])
fromList [(3,3),(5,4)]
ghci> updateAt f 1 (fromList [(5,4), (3,1)])
fromList [(3,1)]
ghci> updateAt f 2 (fromList [(5,4), (3,1)])
fromList *** Exception: Map.updateAt: index out of range
ghci> deleteAt 0 (fromList [(5,4), (3,1)])
fromList [(5,4)]
ghci> deleteAt 1 (fromList [(5,4), (3,1)])
fromList [(3,1)]
ghci> deleteAt 2 (fromList [(5,4), (3,1)])
fromList *** Exception: Map.deleteAt: index out of range

5 Subdiccionarios

ghci> isSubmapOf (fromList [(5,2),(3,7)]) (fromList [(3,7),(5,2),(7,8)])
True
ghci> isSubmapOf (fromList [(5,2),(3,7)]) (fromList [(3,4),(5,2),(7,8)])
False
ghci> isSubmapOfBy (<=) (fromList [(5,2),(3,7)]) (fromList [(3,7),(5,4),(7,8)])
True
ghci> isSubmapOfBy (<=) (fromList [(5,2),(3,7)]) (fromList [(3,1),(5,6),(7,8)])
False
ghci> isProperSubmapOf (fromList [(5,2),(3,7)]) (fromList [(3,7),(5,2),(7,8)])
True
ghci> isProperSubmapOf (fromList [(5,2),(3,7)]) (fromList [(3,7),(5,2)])
False
ghci> isProperSubmapOfBy (<=) (fromList [(5,2),(3,7)]) (fromList [(3,7),(5,4),(7,8)])
True
ghci> isProperSubmapOfBy (<=) (fromList [(5,2),(3,7)]) (fromList [(3,7),(5,4)])
False

6 Elementos mínimos y máximos

ghci> findMin (fromList [(5,1), (3,7)])
(3,7)
ghci> findMin empty
*** Exception: Map.findMin: empty map has no minimal element
ghci> findMax (fromList [(5,1), (3,7)])
(5,1)
ghci> findMax empty
*** Exception: Map.findMax: empty map has no maximal element
ghci> deleteMin (fromList [(5,1), (3,7)])
fromList [(5,1)]
ghci> deleteMin empty
fromList []
ghci> deleteMax (fromList [(5,1), (3,7)])
fromList [(3,7)]
ghci> deleteMax empty
fromList []
ghci> let f x = if x < 5 then Just (x+1) else Nothing
ghci> updateMin f (fromList [("p",7),("b",3)])
fromList [("b",4),("p",7)]
ghci> updateMin f (fromList [("p",7),("b",6)])
fromList [("p",7)]
ghci> let f x = if x < 5 then Just (x+1) else Nothing
ghci> updateMax f (fromList [("p",2),("b",6)])
fromList [("b",6),("p",3)]
ghci> updateMax f (fromList [("p",7),("b",6)])
fromList [("b",6)]
ghci> let f k x = if odd x then Just (k*x) else Nothing
ghci> updateMinWithKey f (fromList [(3,7),(4,5)])
fromList [(3,21),(4,5)]
ghci> updateMinWithKey f (fromList [(3,6),(4,5)])
fromList [(4,5)]
ghci> let f k x = if odd x then Just (k*x) else Nothing
ghci> updateMaxWithKey f (fromList [(3,6),(4,5)])
fromList [(3,6),(4,20)]
ghci> updateMaxWithKey f (fromList [(3,6),(4,8)])
fromList [(3,6)]
ghci> minView (fromList [(5,"a"), (3,"b")])
Just ("b",fromList [(5,"a")])
ghci> minView empty
Nothing
ghci> maxView (fromList [(5,"a"), (3,"b")])
Just ("a",fromList [(3,"b")])
ghci> maxView empty
Nothing
ghci> minViewWithKey (fromList [(5,"a"), (3,"b")])
Just ((3,"b"),fromList [(5,"a")])
ghci> minViewWithKey empty
Nothing
ghci> maxViewWithKey (fromList [(5,"a"), (3,"b")])
Just ((5,"a"),fromList [(3,"b")])
ghci> maxViewWithKey empty
Nothing
ghci> deleteFindMin (fromList [(5,"a"),(3,"b"),(10,"c")])
((3,"b"),fromList [(5,"a"),(10,"c")])
ghci> deleteFindMax (fromList [(5,"a"),(3,"b"),(10,"c")])
((10,"c"),fromList [(3,"b"),(5,"a")])

7 Operaciones con diccionarios

7.1 Unión

ghci> union (fromList [(5,7),(3,4)]) (fromList [(5,9),(7,2),(6,1)])
fromList [(3,4),(5,7),(6,1),(7,2)]
ghci> unionWith (+) (fromList [(5,7),(3,4)]) (fromList [(5,9),(7,2),(6,1)])
fromList [(3,4),(5,16),(6,1),(7,2)]
ghci> let f k x y = k*(x+y)
ghci> unionWithKey f (fromList [(5,7),(3,4)]) (fromList [(5,9),(3,2)])
fromList [(3,18),(5,80)]
ghci> unions [fromList [(5,7)], fromList [(5,9),(3,4)], fromList [(3,8)]]
fromList [(3,4),(5,7)]
ghci> unionsWith (+) [fromList [(5,7)], fromList [(5,9),(3,4)], fromList [(3,8)]]
fromList [(3,12),(5,16)]

7.2 Intersección

ghci> intersection (fromList [(5,7),(3,4)]) (fromList [(5,9),(7,2),(6,1)])
fromList [(5,7)]
ghci> intersectionWith (+) (fromList [(5,7),(3,4)]) (fromList [(5,9),(7,2),(6,1)])
fromList [(5,16)]
ghci> let f k x y = k*(x+y)
ghci> intersectionWithKey f (fromList [(5,7),(3,4)]) (fromList [(5,9),(4,2)])
fromList [(5,80)]

7.3 Diferencia

ghci> difference (fromList [(5,7),(3,4)]) (fromList [(5,9),(7,2),(6,1)])
fromList [(3,4)]
ghci> fromList [(5,7),(3,4)] \\ fromList [(5,9),(7,2),(6,1)]
fromList [(3,4)]
ghci> let f x y = if x < y then Just (x+y) else Nothing
ghci> differenceWith f (fromList [(5,1),(3,4)]) (fromList [(5,2),(7,2)])
fromList [(3,4),(5,3)]
ghci> differenceWith f (fromList [(5,6),(3,4)]) (fromList [(5,2),(7,2)])
fromList [(3,4)]
ghci> let f k x y = if x+y < k then Just (x+y) else Nothing
ghci> differenceWithKey f (fromList [(5,1),(3,4)]) (fromList [(5,2),(7,2)])
fromList [(3,4),(5,3)]
ghci> differenceWithKey f (fromList [(5,6),(3,4)]) (fromList [(5,2),(7,2)])
fromList [(3,4)]

8 Funciones de orden superior

8.1 Filtrados y particiones

ghci> M.filter (>5) (fromList [("b",4),("e",8),("d",3),("a",7)])
fromList [("a",7),("e",8)]
ghci> let p k x = k >= x
ghci> M.filterWithKey p (fromList [(8,4),(3,8),(7,3),(6,7)])
fromList [(7,3),(8,4)]
ghci> partition (>6) (fromList [(8,4),(3,8),(7,3),(6,7)])
(fromList [(3,8),(6,7)],fromList [(7,3),(8,4)])
ghci> let p k x = k >= x
ghci> partitionWithKey p (fromList [(8,4),(3,8),(7,3),(6,7)])
(fromList [(7,3),(8,4)],fromList [(3,8),(6,7)])
ghci> split 5 (fromList [(7,'a'),(4,'b'),(6,'b'),(5,'e')])
(fromList [(4,'b')],fromList [(6,'b'),(7,'a')])

8.2 Aplicaciones ("map")

ghci> M.map (+1) (fromList [(8,4),(3,8),(7,3),(6,7)])
fromList [(3,9),(6,8),(7,4),(8,5)]
ghci> fmap (+1) (fromList [(8,4),(3,8),(7,3),(6,7)])
fromList [(3,9),(6,8),(7,4),(8,5)]
ghci> let f k x = k + x
ghci> mapWithKey f (fromList [(8,4),(3,8),(7,3),(6,7)])
fromList [(3,11),(6,13),(7,10),(8,12)]
ghci> mapKeys (+ 1) (fromList [(5,"a"), (3,"b")])
fromList [(4,"b"),(6,"a")]
ghci> mapKeys (+ 1) (fromList [(5,"a"), (3,"b"), (5,"d")])
fromList [(4,"b"),(6,"d")]
ghci> mapKeysWith (++) (^2) (fromList [(-1,"a"), (1,"b"), (2,"d")])
fromList [(1,"ba"),(4,"d")]
ghci> let f x = if x < 5 then Just (x+1) else Nothing
ghci> mapMaybe f (fromList [(2,4),(6,8),(4,3),(9,7)])
fromList [(2,5),(4,4)]
ghci> let f k x = if k < x then Just (x+1) else Nothing
ghci> mapMaybeWithKey f (fromList [(2,4),(6,8),(4,3),(9,7)])
fromList [(2,5),(6,9)]
ghci> let f x y = (x-y,2*x)
ghci> mapAccum f 10 (fromList [(5,7),(3,2)])
(1,fromList [(3,20),(5,16)])
ghci> let f a b = (a ++ b, b ++ "X")
ghci> mapAccum f "Res: " (fromList [(5,"a"), (3,"b")])
("Res: ba",fromList [(3,"bX"),(5,"aX")])
ghci> let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")
ghci> mapAccumWithKey f "Res:" (fromList [(5,"a"), (3,"b")])
("Res: 3-b 5-a",fromList [(3,"bX"),(5,"aX")])

8.3 Plegados

ghci> M.foldr (-) 0 (fromList [('a',3),('b',2),('c',4)])
5
ghci> Prelude.foldr (-) 0 [3,2,4]
5
ghci> 3-(2-(4-0))
5
ghci> M.foldr (-) 0 (fromList [('a',3),('c',4),('b',2)])
5
ghci> M.foldr' (-) 0 (fromList [('a',3),('b',2),('c',4)])
5
ghci> M.foldl (-) 0 (fromList [('a',3),('b',2),('c',4)])
-9
ghci> Prelude.foldl (-) 0 [3,2,4]
-9
ghci> ((0-3)-2)-4
-9
ghci> M.foldl (-) 0 (fromList [('a',3),('c',4),('b',2)])
-9
ghci> M.foldl' (-) 0 (fromList [('a',3),('b',2),('c',4)])
-9
ghci> let f k v s = s ++ (replicate k v)
ghci> foldrWithKey f "" (fromList [(5,'a'), (3,'b')]) 
"aaaaabbb"
ghci> let f k v s = k*v-s
ghci> foldrWithKey f 0 (fromList [(1,7),(2,8),(3,5)])
6
ghci> let f k v s = k*v-s
ghci> let f k v s = s ++ (replicate k v)
ghci> foldrWithKey' f "" (fromList [(5,'a'), (3,'b')]) 
"aaaaabbb"
ghci> let f k v s = k*v-s
ghci> foldrWithKey' f 0 (fromList [(1,7),(2,8),(3,5)])
6
ghci> let f s k v = s ++ replicate k v
ghci> foldlWithKey f "" (fromList [(5,'a'), (3,'b')]) 
"bbbaaaaa"
ghci> let f s k v = s-k*v
ghci> foldlWithKey f 0 (fromList [(1,7),(2,8),(3,5)])
-38
ghci> ((0-1*7)-2*8)-3*5
-38
ghci> let f s k v = s ++ replicate k v
ghci> foldlWithKey' f "" (fromList [(5,'a'), (3,'b')]) 
"bbbaaaaa"
ghci> let f s k v = s-k*v
ghci> foldlWithKey' f 0 (fromList [(1,7),(2,8),(3,5)])
-38
ghci> ((0-1*7)-2*8)-3*5
-38

9 Conversiones

9.1 De diccionarios a listas y conjuntos

ghci> elems (fromList [(1,7),(3,5),(2,8)])
[7,8,5]
ghci> keys (fromList [(1,7),(3,5),(2,8)])
[1,2,3]
ghci> assocs (fromList [(1,7),(3,5),(2,8)])
[(1,7),(2,8),(3,5)]
ghci> toList (fromList [(1,7),(3,5),(2,8)])
[(1,7),(2,8),(3,5)]
ghci> keysSet (fromList [(1,7),(3,5),(2,8)])
fromList [1,2,3]

9.2 De listas y conjuntos a diccionarios

ghci> fromList [(5,"a"),(3,"b"),(5,"c")]
fromList [(3,"b"),(5,"c")]
ghci> fromList [(5,"a"),(3,"b"),(5,"c"),(3,"a")]
fromList [(3,"a"),(5,"c")]
ghci> fromListWith (++) [(5,"a"),(3,"b"),(5,"c")]
fromList [(3,"b"),(5,"ca")]
ghci> fromListWith (++) [(5,"a"),(3,"b"),(5,"c"),(3,"a")]
fromList [(3,"ab"),(5,"ca")]
ghci> fromListWith (-) [(5,4),(3,6),(5,2),(3,1)]
fromList [(3,-5),(5,-2)]
ghci> let f k v1 v2 = show k ++ v1 ++ v2
ghci> fromListWithKey f [(5,"a"),(3,"b"),(5,"c"),(3,"a")]
fromList [(3,"3ab"),(5,"5ca")]
ghci> fromSet (\k -> replicate k 'a') (Data.Set.fromList [3,5])
fromList [(3,"aaa"),(5,"aaaaa")]
ghci> fromSet (*2) (Data.Set.fromList [3,5])
fromList [(3,6),(5,10)]

9.3 Conversiones entre diccionarios y listas ordenadas

ghci> toAscList (fromList [(5,"a"), (3,"b")])
[(3,"b"),(5,"a")]
ghci> toDescList (fromList [(5,"a"), (3,"b")])
[(5,"a"),(3,"b")]
ghci> fromAscList [(3,"b"),(5,"a"),(5,"c")]
fromList [(3,"b"),(5,"c")]
ghci> fromAscListWith (++) [(3,"b"),(5,"a"),(5,"c")]
fromList [(3,"b"),(5,"ca")]
ghci> let f k v1 v2 = show k ++ v1 ++ v2
ghci> fromAscListWithKey f [(3,"a"),(3,"b"),(5,"c"),(5,"a")]
fromList [(3,"3ba"),(5,"5ac")]

10 Diccionarios y árboles

ghci> putStrLn (showTree (fromList [(8,'b'),(3,'a'),(7,'d'),(6,'c')]))
7:='d'
+--3:='a'
|  +--|
|  +--6:='c'
+--8:='b'

ghci> putStrLn (showTree (fromList [(n,2*n) | n <- [1..5]]))
2:=4
+--1:=2
+--4:=8
   +--3:=6
   +--5:=10

ghci> putStrLn (showTree (fromList [(n,2*n) | n <- [5,4..1]]))
4:=8
+--2:=4
|  +--1:=2
|  +--3:=6
+--5:=10
ghci> let d = fromList [(n,2*n) | n <- [1..5]]
ghci> let f k v = show (k,v)
ghci> putStrLn $ showTreeWith f True False d
(2,4)
+--(1,2)
+--(4,8)
   +--(3,6)
   +--(5,10)

ghci> putStrLn $ showTreeWith f True True d
(2,4)
|
+--(1,2)
|
+--(4,8)
   |
   +--(3,6)
   |
   +--(5,10)

ghci> putStrLn $ showTreeWith f False True d
   +--(5,10)
   |
+--(4,8)
|  |
|  +--(3,6)
|
(2,4)
|
+--(1,2)

ghci> putStrLn $ showTreeWith f False False d
   +--(5,10)
+--(4,8)
|  +--(3,6)
(2,4)
+--(1,2)