hubFS: THE place for F#

. . . are you on The Hub?
Welcome to hubFS: THE place for F# Sign in | Join | Help
in Search

How to create and update a Map object

Last post 10-14-2007, 23:25 by jhugard. 2 replies.
Sort Posts: Previous Next
  •  07-05-2006, 19:41 411

    How to create and update a Map object

    I was going through the F# documentation for MLib.Map. I was having trouble understanding how to create and update a map. I could not find any relevant articles at the usual web sites. Here is a rather contrived example to describe the problem.

    type dayofweek = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday

    type daycategory = Weekday | Weekend

    let dow_index d = match d with 
             Monday -> 1 | Tuesday -> 2 | Wednesday -> 3 | Thursday -> 4
             | Friday -> 5 | Saturday -> 6 | Sunday -> 7
             
    let day_compare d1 d2 = dow_index(d1) - dow_index(d2)

    // This is the map object.
    let is_weekend = let m : (dayofweek, daycategory) Map.CMapOps = Map.Make(day_compare) in
                        [Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;Sunday] |>
                        List.iteri(fun i w ->  let x = if i < 5 then Weekday else Weekend in
                                                m.add w x |> ignore); // Here is where I am having trouble. How do I add 
                                                                                 // elements to the map.
                                                m


    Also can I just start of with Map.empty and then add elements to the map?

    Thanks in advance

    Chris
  •  07-05-2006, 20:56 412 in reply to 411

    Re: How to create and update a Map object

    Use my all time favourite function... fold... in this case, left fold

    type dayofweek = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday

    type daycategory = Weekday | Weekend

    let is_weekend =
      let f day = if (day = Saturday) || (day = Sunday) then Weekday else Weekend in
        List.fold_left
          (fun map day -> Map.add day (f day) map)
          Map.empty
          [Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;Sunday]


    As comparison is auto implemented for dayofweek... the custom comparison code is not need... at least for this section... and because of that you don't need to 'make' the map with a custom comparator... the standard map functions will use the built in *compare* (Pervasives).

    see previous article: http://cs.hubfs.net/blogs/f_team/archive/2006/05/11/247.aspx
  •  10-14-2007, 23:25 3752 in reply to 411

    Re: How to create and update a Map object

    (yes, this is a stale post - but since I had the same problem, figure I'll add an explanation to DeeJay's code to help out the next guy...)

    The heart of the matter is that F#'s containers are all done in a "functional" style.  Basically, this means they are immutable.  Instead of manipulating elements held in a single mutable map object, the Map.add function returns a new map comprised of the given map and the supplied new key/element pair.

    While it would be easy enough to substitute System.Collections.Generic.Dictionary into your code, let's take a look at how to use the Map in a functional setting.

    The inner loop in DeeJay's code above (modified slightly, below) uses "List.fold_left" to accumulate a map with the keys found from a supplied list and an associated boolean value.  The fold_left function accumulates intermediate maps as it folds the list (starting at the left), then returns the final accumulated resulting Map.  Since the inner nodes in each intermediate map are shared between each of these maps, the operation is fairly efficient in both time and space.

    #light

    type dayofweek = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday

     

    let is_weekend_map =

     

    let isWeekend day = match day with

    | Saturday | Sunday -> true

    | _ -> false

     

    [Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;Sunday]

    |> List.fold_left

    (fun acc key ->

                   acc

                   |> Map.add key (isWeekend key) )

    Map.empty

     


    "It seems that perfection is reached, not when there is nothing left to add, but rather when nothing more can be taken away." -- Antoine de St. Exupéry
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems