I have defined the following interface and module:
module type TYPE =
sig
type t
end
module Type = (struct
type t =
| TBot
| T of int
| TTop
end: TYPE)
Now I realize that If I write outside Type.T 5
, the compiler will give me en error Error: Unbound constructor Type.T
. If I remove the signature and keep the module, the error will disappear.
1) So my first question is, how to change the signature such that I can use the constructors outside?
2) One way is to define a constructor explicitly as follows, do you think it is a conventional way? One disadvantage I can see now is it does not allow to construct TBot
or TTop
.
module type TYPE =
sig
type t
val make : int -> t
end
module Type = (struct
...
let make (i: int) : t =
T i
end: TYPE)
3) Is it always necessary to let outside be able to construct a value inside a module?
1) You have to export the type declaration, otherwise, t
is considered as abstract and then you need to define and export constructors (see 2)):
module type TYPE = sig
type t =
| TBot
| T of int
| TTop
end
module Type : TYPE = struct
type t =
| TBot
| T of int
| TTop
end
2) Yes, it is a perfectly fine way. To define top and bottom, you just have to define (and export) new constructors:
module type TYPE = sig
...
val top: t
val bot: t
end
module Type = struct
...
let bot = TBot
let top = TTop
end
3) I don't get your question
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