Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ocaml 类型定义中的断言_Ocaml_Assert - Fatal编程技术网

Ocaml 类型定义中的断言

Ocaml 类型定义中的断言,ocaml,assert,Ocaml,Assert,我有一些类型 type my_type_name = | A of (float * float) | B of (float * float) | E ;; 我知道我的代码有问题,如果p>=q在B(p,q)或A(p,q)。所以我想在类型中做断言,这样如果我尝试做A(5,1)它就会通知我 是否可以在类型构造函数中进行断言?应该是什么样子 我试图避免这样的事情: assert (p < q) ; A(p, q) assert(p

我有一些类型

type my_type_name =
    | A of (float * float)
    | B of (float * float)
    | E
;;
我知道我的代码有问题,如果
p>=q
B(p,q)
A(p,q)
。所以我想在类型中做断言,这样如果我尝试做
A(5,1)
它就会通知我

是否可以在类型构造函数中进行断言?应该是什么样子

我试图避免这样的事情:

assert (p < q) ; A(p, q)
assert(p

因为我在代码中有很多a或B对象。

没有直接的方法将这样的断言放入类型定义本身

一种很好的方法是将类型定义为抽象类型(在模块中)并导出函数以构造该类型的值。这是生成该类型值的唯一方法,您可以在函数中包含任何您喜欢的断言

更新


正如@antron指出的,将类型设置为私有而不是抽象可能更适合您的问题。

@Jeffrey Scofield已经给出了一个完全准确的答案,但下面是所要求的示例:

module type MY_TYPE =
sig
  type my_type_name = private
    | A of (float * float)
    | B of (float * float)
    | E

  val a : float -> float -> my_type_name
  val b : float -> float -> my_type_name
  val e : my_type_name
end

module My_type : MY_TYPE =
struct
  type my_type_name =
    | A of (float * float)
    | B of (float * float)
    | E

  let a p q = assert true; A (p, q)
  let b p q = assert true; B (p, q)
  let e = E
end

let () =
  (* My_type.A (1., 2.); *)    (* Type error - private type. *)
  let x = My_type.a 1. 2. in

  (* Can still pattern match. *)
  match x with
  | My_type.A (_, _) -> ()
  | My_type.B (_, _) -> ()
  | My_type.E -> ()
签名的主体可以是
.mli
文件,而
My_type
的主体可以是
.ml
文件。关键是
my\u type\u name
后面是
my\u type
中的关键字
private
。这导致直接使用底部的构造函数被标记为错误,迫使所有构造都经过函数
a
b
e
,在这些函数中可以包含断言或任意其他表达式


编辑为了使函数看起来更像构造函数,当然可以将其参数转换为元组类型。要使模块几乎透明,您可以
在底部打开它。但这些都是品味的问题,取决于你。

作为一种改进,你可以将类型私有化,而不是完全抽象,因此你仍然可以在其上进行模式匹配,但必须通过可见函数进行构造。antron,@JeffreyScofield:感谢你们两位的帮助。