Reputation: 3
I'm working on an OCaml project where I've defined a functor-based dictionary using modules and functors. I've encountered a type mismatch error when trying to insert elements into the dictionary. I've used a functor MakeListDictionary
to create a dictionary module ListDict
with integer keys and values.
(* The code is about a List based dictionary, and when use insert function, it throws an error. *)
module type Formattable = sig
type t
val format : Format.formatter -> t -> unit
end
module type Comparable = sig
type t
val compare : t -> t -> [ `EQ | `GT | `LT ]
include Formattable with type t := t
end
module IntComparable : Comparable = struct
type t = int
let compare x y = if x < y then `LT else if x > y then `GT else `EQ
let format fmt t = Format.fprintf fmt "%d" t
end
module IntFormattable : Formattable = struct
type t = int
let format fmt t = Format.fprintf fmt "%d" t
end
let dict = ListDict.empty;;
ListDict.insert 1 1 dict;;
When I try to insert a key-value pair into the dictionary using ListDict.insert 1 1 dict, I receive the following error message:
Error: This expression has type int but an expression was expected of type ListDict.key
I'm confused because ListDict.key is an alias for IntComparable.t, which in turn is just an alias for int. I expected that passing integers directly to the insert function would work. Could someone explain why this type mismatch error is occurring and how to resolve it? Any insights or suggestions would be greatly appreciated.
Could someone explain why this type mismatch error is occurring and how to resolve it? Any insights or suggestions would be greatly appreciated.
Upvotes: 0
Views: 62
Reputation: 36611
The Comparable
and Formattable
module types say nothing about the nature of type t
. By applying the Comparable
and Formattable
module types to IntComparable
and IntFormattable
you have made their t
types abstract. You need to explicitly expose those types if you want to know anything about them outside of the module.
module IntComparable : Comparable with type t = int = struct
type t = int
let compare x y =
if x < y then `LT
else if x > y then `GT
else `EQ
let format fmt t = Format.fprintf fmt "%d" t
end
module IntFormattable : Formattable with type t = int = struct
type t = int
let format fmt t = Format.fprintf fmt "%d" t
end
Now:
# ListDict.insert 1 1 dict;;
- : (int * int) list = [(1, 1)]
Alternatively, let structural typing of modules do its thing and elide the module type signature constraints so that the t
types are not abstract.
module IntComparable = struct
type t = int
let compare x y =
if x < y then `LT
else if x > y then `GT
else `EQ
let format fmt t = Format.fprintf fmt "%d" t
end
module IntFormattable = struct
type t = int
let format fmt t = Format.fprintf fmt "%d" t
end
Upvotes: 1