The problem is that F# doesn't support functors. Here's how you'd use the Map.Make function in F#:

1
let intMap = Map.Make<int, int>(fun x y -> x.CompareTo(y))

However, you only really need to do that if you want to use a custom comparison of your keys, otherwise you can just use Map.empty with some type annotations:

1
2
3
let (emptyIntMap: Map<int, int>) = Map.empty

let oneIntMap = emptyIntMap.Add(1, 1)
By on 2/22/2008 4:33 AM ()

Ah, no functors, ok then.

As i want to make the same as that line in Ocaml did:

1
 module IntMap = Map.Make (struct type t = int let compare = compare end) 

I've thought that i could create another file, named 'intmap.fs', and then define it like that:

1
2
3
4
5
6
7
8
9
10
 type t = int

let empty = Map.empty

let is_empty = Map.is_empty

let add = Map.add

// .... you get the idea 

But for some reason i'm not having the desired result, still get some type conflicts after using this work-around:

...

1
 type 'a t = <i>'a IntMap.t<i> 

-> <i>type constructor 'IntMap.t' expects 0 type argument(s) but its give 1.<i> ... Any ideas wath am i doing wrong?

By on 2/22/2008 3:35 PM ()

I'm not sure where the specific error your getting comes from but I don't think you need to do that. Once you've called the Map module's Make function you get a value that behaves almost exactly like an ocaml module:

1
2
3
4
5
6
let IntMap = Map.Make<int, int>(fun x y -> x.CompareTo(y))

let x = IntMap.empty
let x1 = IntMap.add 1 1 x 
let x2 = IntMap.add 2 2 x1 
let x3 = IntMap.map (fun x -> x + 1) x2

Is your concern cross compilation? I believe you use a #if and a define on the command line to optional compile either the "let IntMap ..." or the "module IntMap ..." line and the rest of the code should not need changing.

Cheers,
Rob

By on 2/22/2008 11:28 PM ()

I don't wanna cross-compile, just want to make in F# wath that line does in Ocaml.

So following your advice i now got:

1
2
3
4
5
6
7
8
9
10
11
12
13
module IntMap = struct

type 'a t = int

let IntMap2 = Map.Make<int, int>(fun x y -> x.CompareTo(y))

let empty = IntMap2.empty

let add = IntMap2.add

//....

end

I made it that way, because by just making

1
let IntMap = Map.Make<int, int>(fun x y -> x.CompareTo(y))

i get problems trying to access the type:

1
 type 'a t = 'a IntMap.t  

-><i>the namespace or module 'IntMap' is not defined.<i> Anyway i still got problems due to the type i think. The line <code lang=fsharp> module IntMap = Map.Make(struct type t = int let compare = compare end)</code> regarding the type, does not simply do that: <code lang=fsharp> type 'a t = int </code> ? I think the problem is on the type because the remaining errors i got on the project are all like this: <code lang=fsharp> 'hstring.fs' type t = {str : string; add: int} </code> 'anotherFile.fs' <code lang=fsharp> type t = { .... mutable strings = Hstring.t IntMap.t; ...} strings= <i>IntMap.empty<i> </code>-> <i>This expression has type Tagged.Map<int , int, System.Collections.Generic.IComparer<int>> but is here used with type t IntMap.t<i> Any clue wath am i doing wrong?

By on 2/24/2008 10:11 AM ()

Case solved.

Implemented myself the 'intmap.fs' file, coding the functions and type definition i needed: intmap.add, intmap.mem, ...

Probably not the best solution, but the only way that worked for me.

By on 2/26/2008 8:51 AM ()

Hi,
sorry for the late reply, but I think there is better solution then rewriting all the functions manually. The problem is that the "IntMap" created using F# "Map.Make" function doesn't contain the declaration of "t" (the type of the item stored in the map). This is probably because there is no reasonable way to do this in .NET.

That said you can't use "IntMap.t", but all the functions should be available. You can declare a module containing this missing type declaration in a single file, so you can write something like this:

1
2
3
4
5
6
7
8
9
 
#light
module MyUtils 

// Contains the functions for working with int maps
let IntMap = Map.Make<int, int>(fun x y -> x.CompareTo(y))
// Contains just the 't' type, so you can use "IntMap.t" in your code
module IntMap = 
  type t = int

The code that uses this IntMap would be something like this:

1
2
3
4
5
6
7
 
#light
open MyUtils

let x = IntMap.empty
let (v:IntMap.t) = 0
// ...
By on 2/29/2008 1:18 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper