Haskell Language Containers - Data.Map


We can create a Map from a list of tuples like this:

Map.fromList [("Alex", 31), ("Bob", 22)]

A Map can also be constructed with a single value:

> Map.singleton "Alex" 31
fromList [("Alex",31)]

There is also the empty function.

empty :: Map k a

Data.Map also supports typical set operations such as union, difference and intersection.

Checking If Empty

We use the null function to check if a given Map is empty:

> Map.null $ Map.fromList [("Alex", 31), ("Bob", 22)]

> Map.null $ Map.empty

Finding Values

There are many querying operations on maps.

member :: Ord k => k -> Map k a -> Bool yields True if the key of type k is in Map k a:

> Map.member "Alex" $ Map.singleton "Alex" 31
> Map.member "Jenny" $ Map.empty

notMember is similar:

> Map.notMember "Alex" $ Map.singleton "Alex" 31
> Map.notMember "Jenny" $ Map.empty

You can also use findWithDefault :: Ord k => a -> k -> Map k a -> a to yield a default value if the key isn't present:

Map.findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'
Map.findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'

Inserting Elements

Inserting elements is simple:

> let m = Map.singleton "Alex" 31
fromList [("Alex",31)]

> Map.insert "Bob" 99 m
fromList [("Alex",31),("Bob",99)]

Deleting Elements

> let m = Map.fromList [("Alex", 31), ("Bob", 99)]
fromList [("Alex",31),("Bob",99)]

> Map.delete "Bob" m
fromList [("Alex",31)]

Importing the Module

The Data.Map module in the containers package provides a Map structure that has both strict and lazy implementations.

When using Data.Map, one usually imports it qualified to avoid clashes with functions already defined in Prelude:

import qualified Data.Map as Map

So we'd then prepend Map function calls with Map., e.g.

Map.empty -- give me an empty Map

Monoid instance

Map k v provides a Monoid instance with the following semantics:

  • mempty is the empty Map, i.e. the same as Map.empty
  • m1 <> m2 is the left-biased union of m1 and m2, i.e. if any key is present both in m1 and m2, then the value from m1 is picked for m1 <> m2. This operation is also available outside the Monoid instance as Map.union.