C# Dictionary to F# Map
Following on from my past blog on effective parallelism I’ve continued digging into the functional language F#. I’m getting there – slowly and I am loving immutability. It’s quite a mindset change from my day-to-day work in imperative languages but I can see a little bit of progress in my functional thinking every day.
I’m doing quite a lot of C#->F#->C# interop (writing a distributed Erlang-like message passer, with agents using F#’s MailboxProcessor) and I came across a problem where I needed to convert a Dictionary produced in my C# layer to an immutable F# equivalent: Map.
Digging around online so far regarding F# is proving slow, it’s a new language, and there isn’t the plethora of code-snippets there are for other languages. The F# Manual also is nothing like MSDN – where code-snippets and examples are all over the place.
Anyway, here is a trivial little example of what I have come up with. I have an F# assembly, TestMap.dll, which exposes a module TestMap. A type in this module, ExampleDictionaryToMap, has a method Convert that takes a C# Dictionary and returns an F# immutable
The F# performing the conversion:
#light
module TestMap
open System.Collections.Generic
type ExampleDictionaryToMap =
// Convert a C# Dictionary<string,int> to a Map<string,int>
static member Convert(_dict: Dictionary<string, int>) =
List.fold_left (fun acc idx -> Map.add idx _dict.[idx] acc) Map.empty (Seq.to_list _dict.Keys)
// Convert a C# Dictionary<string,int> to a Map<string,int>
// Steps are broken down:-
// (1) define an accumulator: function "accumulator"
// (2) define an initial value for the accumulator: "initialAccumulatorValue"
// (3) create the list to fold using Seq.to_list on the C# Dictionaries Keys emuerator: "list"
static member StepByStepConvert(_dict: Dictionary<string, int>) =
let accumulator acc idx = Map.add idx _dict.[idx] acc
let initialAccumulatorValue = Map.empty
let list = Seq.to_list _dict.Keys
List.fold_left accumulator initialAccumulatorValue list
Then calling this F# from C#, Map is the F# type from Fsharp.Core:
Dictionary<string, int> csharpDictionary = new Dictionary<string,int>();
csharpDictionary.Add("value1", 1);
csharpDictionary.Add("value2", 2);
csharpDictionary.Add("value3", 3);
csharpDictionary.Add("value4", 4);
Map<string,int> fsharpMap = TestMap.ExampleDictionaryToMap.Convert(csharpDictionary);
I’m sure there is a more efficient way so any comments welcome!
Tags: C#, Erlang, F#, Functional Languages
July 19th, 2008 at 6:27 pm
I think Map.of_seq is the simplest way to do the conversion; consider:
#light
open System.Collections.Generic
let d = new Dictionary()
d.["one"] <- 1
d.["two"] <- 2
d.["three"] seq)
let m = keyValuePairs |> Seq.map (fun kvp -> (kvp.Key, kvp.Value)) |> Map.of_seq
for kvp in m do
printfn “%s -> %d” kvp.Key kvp.Value
July 19th, 2008 at 7:47 pm
Looks like many angle brackets were swallowed… trying again
#light
open System.Collections.Generic
let d = new Dictionary<string,int>()
d.["one"] <- 1
d.["two"] seq<_>)
let m = keyValuePairs |> Seq.map (fun kvp -> (kvp.Key, kvp.Value)) |> Map.of_seq
for kvp in m do
printfn “%s -> %d” kvp.Key kvp.Value
July 19th, 2008 at 7:49 pm
Looks like angle brackets were swallowed… trying again
#light
open System.Collections.Generic
let d = new Dictionary<string,int>()
d.["one"] <- 1
d.["two"] <- 2
d.["three"] <- 3
let keyValuePairs = (d :> seq<_>)
let m = keyValuePairs |> Seq.map (fun kvp -> (kvp.Key, kvp.Value)) |> Map.of_seq
for kvp in m do
printfn “%s -> %d” kvp.Key kvp.Value
December 22nd, 2008 at 5:41 pm
Tim, a quick hello from someone following much the same path, moving in a functional direction after many years in C/C++/C# land.
I’ve found the process slow, and the learning curve painfully steep, but completely fascinating, and rewarding. There’s a dearth of good books, but if you have a solid grasp of the basics “F# for Scientists” is pretty good.
A dictionary enumerates as a sequence of KeyValuePairs, so if d is the same Dictionary as above
d |> Seq.fold_left (fun acc kvp -> acc.add kvp.Key kvp.Value) Map.empty
is all you need.
I’m translating “Programming Collective Intelligence”, a pretty damn interesting book on data analysis - something I’m sure you MMO guys are all over - into F# over at http://code.google.com/p/dataviz
I don’t have much to show for it yet, but it’s powerful stuff. Take a look if your interested.
http://cs.hubfs.net/ is also worth looking at if you haven’t already.