Search code examples
haskellhashtable

An example of using Data.Map in Haskell


I'm new in Haskell and I need to define an empty Data.map and assigning a "list of integers" (e.g. [1,2,3]) to its keys by using insert function and also updating the values. Then looking up the key values.

What I have tried so far is :

import qualified Data.Map

foo num =
    let
        my_map  = Data.Map.empty

        new_map = bar my_map  num 1

    in
        Data.Map.lookup 1 new_map


bar my_map num c =
    if c > num then my_map
    else
        Data.Map.insert  c  [c] my_map
        bar my_map  num  c+1

This code doesn't work.

Could you have a simple example please?


Solution

  • People normally import the Data.Map module with this boilerplate:

    import Data.Map (Map)
    import qualified Data.Map as Map
    

    The idea is that since many of the names in the module clash with the Prelude and other modules, you want to use them as qualified names—but not for the Map type itself. And the as Map bit in the second line saves you from having to type as much—you just say Map.map, Map.empty, etc.

    Now, the easiest and most common way of constructing a map is to use the fromList function in the module. This constructs a Map from a list of key/value pairs: Map.fromList :: Ord k => [(k, v)] -> Map k v. To construct this list of key/value pairs you can use the full power of Haskell's list processing functions, like in this example:

    myMap :: Integer -> Map Integer [Integer]
    myMap n = Map.fromList (map makePair [1..n])
        where makePair x = (x, [x])
    

    Example output in GHCI:

    >>> myMap 3
    fromList [(1,[1]),(2,[2]),(3,[3])]
    

    Note that the Map type even prints itself as a fromList call that would reconstruct it. Why? Because again, this function really is the most common way to build a Map.

    In contrast, what you're doing in your code is you're trying to write an imperative-style loop that successively augments an initial empty map with entries one at a time. The Haskell equivalent of loops is list functions. In my version I used the following:

    1. [1..n]—generate a list of the integers from 1 up to n.
    2. map—apply a function to each element of the list.
    3. Map.fromList—build a Map from a list of key/value pairs.

    And to further demonstrate that point, if you look at the source code for Map.fromList, it's actually defined using a list fold function.

    My advise to you: study lists and the Data.List module first before you tackle Map. In particular:

    1. Learn what functions are available there and what to do.
    2. Study the foldr function from that module—how to use it, and how to write it.
    3. Learn how to write your own versions of map, filter and find in terms of foldr.