另一種解決方案是定義了私人類型的模塊如下:使用的
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的新手,我不確定你想使用它,但是仍然可以知道它可以完成。
不錯的解決方案。通過這種方式,你甚至可以執行你想得到的算術:+可以觸發一個異常,或者執行一些模塊化的算術。 –