I am working with the Map module in OCaml. Consider the following code to create a map with ints as keys:
module Int = struct
type t = int
let compare a b = a - b
end
module IntMap = Map.Make(Int)
let m = IntMap.(empty |> add 3 "hello")
This all works fine. It compiles and behaves as I would expect.
However, if I add a type annotation for the Int module so the top line becomes:
module Int : Map.OrderedType = struct
The final line causes an error in compilation:
let m = IntMap.(empty |> add 3 "hello")
^
Error: This expression has type int but an expression was expected of type
IntMap.key = Int.t
However IntMap.key and Int.t are both just an alias for int. Furthermore the Int module is of type Map.OrderedType. I know this because that's the required type for Map.Make.
So what an earth is going on here? Why would providing a type annotation that isn't necessary cause an error like this. Do type annotations cause stricter accessibility and not behave the same as inferred types?
This kind of annotation strictly limits the interface of a module. So it seems to me that with the added annotation the only things known about the key type of the map are as given by Map.OrderedType:
module type OrderedType =
sig type t val compare : t -> t -> int end
This says nothing about the type t except that it exists and that it appears in the parameters of compare. In other words, you have hidden the fact that the type t (also known as IntMap.key) is the same type as int.
You can re-introduce this fact using with:
module Int : Map.OrderedType with type t = int = struct
type t = int
let compare a b = a - b
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With