How to write comparer for sorteddictionary?
-
Saturday, May 12, 2012 4:10 AM
i googled c# example and changed as following, not successful
type SortComparer = //: IComparer<array<int>> = let Compare(x : array<int>, y : array<int>) : int = let mutable result : int = 0 if x.[0] > y.[0] then result <- 1 elif x.[0] = y.[0] then result <- 0 else result <- 0 // New DividePoly // Dictionary<(int,int), Coeff) // Dictionary<(degree,degree), Coeff) let NewDividePoly(F : expr, G : expr) : expr = let mutable F_list = DictionaryToList(ExprToDictionary(F)) let mutable G_list = DictionaryToList(ExprToDictionary(G)) let mutable variable_list = getVariableList(F, G) let mutable FDict = new SortedDictionary<array<int>, double>(new SortComparer()) let mutable GDict = new SortedDictionary<array<int>, double>(new SortComparer()) //if variable_list.Count = 2 then for f_term in F_list do let mutable degree_list = Array.init variable_list.Count (fun x -> 0) for f_atom in f_term.Atom do match f_atom with | Atom(S,T,U) -> for i = 0 to variable_list.Count-1 do if variable_list.[i] = T then degree_list.[i] <- U Atom(S,T,U) | S -> S FDict.Add(degree_list,f_term.Coeff) for g_term in G_list do let mutable degree_list = Array.init variable_list.Count (fun x -> 0) for g_atom in g_term.Atom do match g_atom with | Atom(S,T,U) -> for i = 0 to variable_list.Count-1 do if variable_list.[i] = T then degree_list.[i] <- U Atom(S,T,U) | S -> S GDict.Add(degree_list,g_term.Coeff)Just would like to know who is reading my post every day
All Replies
-
Saturday, May 12, 2012 9:41 PM
This is really a question about implementing interfaces in F#, which comes with a well-known gotcha.
F# implements interfaces explicitly by default (exactly the opposite of what happens in C#) and it currently has no way to implement interfaces implicitly. So, either you cast the object to the interface when you need the method, or you write a "forward method" that hides the casting from the caller. So either of these:
type SortComparer0() = // default explicit implementation interface IComparer<array<int>> with member x.Compare(a, b) = // int has a CompareTo method that returns what we want a.[0].CompareTo(b.[0])
// cast explicit implementation let FDict = new SortedDictionary<array<int>, double>(new SortComparer0() :> IComparer<array<int>>)
//------------------------------------------------------------------------------
type SortComparer1() = interface IComparer<array<int>> with member x.Compare(a, b) = if a.[0] > b.[0] then 1 elif a.[0] = b.[0] then 0 else -1 // Forwarding method member x.Compare(a, b) = (x :> IComparer<array<int>>).Compare(a,b) let GDict = new SortedDictionary<array<int>, double>(new SortComparer1())
Note also the simplification of the if/elif/else long-hand implementation -- expressions result in values directly; there's no need to have a value at a level any finer than the if expression. In this case, as that is all there is to the function there's no need even to put that value into a named thing other than the function. And certainly no need for any mutable named thing -- transcribing C# examples into F# needs to be done at a higher level than the individual tokens.
- Marked As Answer by 沈世鈞 Wednesday, May 16, 2012 7:45 AM

