tags:

views:

91

answers:

3

I need to convert a F# map class to a System.Collections.Hashtable for use by C#.

This question is not the same as the following: http://stackoverflow.com/questions/3032298/how-do-you-use-get-values-from-keys-add-items-hashtables-in-f

That question asked how to return values from a hashtable. I want to build an F# map and then convert it to a System.Collections.Hashtable.

How do I do this?

Thanks very much.

Here is what I have tried (does not compile):

#light

open System
open System.Collections
open System.Collections.Generic

let my_map = dict [(1, "one"); (2, "two")]


let myHash = Hashtable()
my_map |> Map.iter (fun k v -> myHash.Add(k, v) ) 

Edit: Thanks for your answers. Here is what I decided to use:

let my_map = Map [(1, "one"); (2, "two")]

let myHash = Hashtable()
my_map |> Map.iter (fun k v -> myHash.Add(k, v))
+4  A: 

This code compiles.

let my_map = Map( [(1, "one"); (2, "two")] )

let myHash = Hashtable()

my_map |> Map.iter (fun k v -> myHash.Add(k, v) ) 

The original one does not compile because the type of dict [(1, "one"); (2, "two")] is IDictionary<int, string>, not Map. And Map.* function family require to operate on F# Map type.

Yin Zhu
+4  A: 

you can use active pattern KeyValuePair

my_map |> Seq.iter(fun (KeyValue (k,v)) -> myHash.Add(k, v))
desco
+4  A: 

If I was writing this, I would probably prefer for loop instead of higher-order function iter. You are writing imperative code (to deal with imperative objects) anyway and I don't think that using iter makes it "more functional". F# provides support for imperative programming as well, so we can use those imperative features in this case:

let myHash = Hashtable() 
for (KeyValue(k, v)) in myMap do
  myHash.Add(k, v)

I usually prefer iter function only when I don't need to write explicit lambda function as the second parameter. For example if the following would work:

myMap |> Seq.iter myHash.Add // This doesn't work, so I prefer 'for' instead

If you have some control over the C# code, you could also consider just using IDictionary<'K, 'V> in C# instead of Hashtable. In that case, you could easily pass F# Map<'K, 'V> as the result, because map implements the IDictionary<'K, 'V> interface (exactly to allow smooth use from C#).

Tomas Petricek