另一种解决方案是定义了私人类型的模块如下:使用的
module type INTERVAL = sig
type t = private int
val of_int : int -> t (* fails if value outside bounds *)
end
let interval a b = (module struct
type t = int
let of_int v =
if v < a || v > b
then failwith (Printf.sprintf "Not in interval [%d, %d]" a b)
else v
end : INTERVAL)
实施例:
let() =
let module Small_int = (val (interval 0 255) : INTERVAL) in
let x = Small_int.of_int (read_int()) in
print_int ((x :> int) * 2)
模块内置这种方式允许您使用有限的一组的整数值的。然而,它们有几个缺点:
- 在使用运算符之前,您必须将值转换回整数(使用:>运算符,如示例所示);
- 该类型本身不给你任何允许的实际边界的信息;您必须查看实现或阅读文档以了解类型的含义;
- 使用的内存空间是一个整数,在这种情况下不是一个字节;
- 如果你实例化两个具有相同边界的模块,它们的类型t将不兼容。
对于第一个缺点,没有什么限制您添加操作模块类型:
module type INTERVAL = sig
type t = private int
val of_int : int -> t
val (+) : t -> t -> t
val print_int : t -> unit
end
let interval a b = (module struct
type t = int
let of_int v =
if v < a || v > b
then failwith "Not in interval"
else v
let (+) x y = of_int (x + y)
let print_int x = print_int x
end : INTERVAL)
let() =
let module Small_int = (val (interval 0 255) : INTERVAL) in
let x = Small_int.of_int (read_int()) in
let y = Small_int.of_int (read_int()) in
Small_int.(print_int (x + y));
print_newline()
第二个缺点可以与你项目的文档中声明的一些约定来克服。
当您想要确保给予函数的输入位于某个“合法”范围内时,这有时很有用。如果你是OCaml的新手,我不确定你想使用它,但是仍然可以知道它可以完成。
不错的解决方案。通过这种方式,你甚至可以执行你想得到的算术:+可以触发一个异常,或者执行一些模块化的算术。 –