How to write comparer for sorteddictionary?

# 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

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

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
•