ocaml - 类型定义中的断言

标签 ocaml assert

我有一些类型

type my_type_name =
    | A of (float * float)
    | B of (float * float)
    | E
;;

而且我知道我的代码有问题,如果 B (p, q)A (p, q) 中的 p >= q 。所以我想在类型中进行断言,这样如果我尝试生成 A (5, 1) 它会通知我。

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

我正在努力避免这样的事情:

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

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

最佳答案

@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_type_name后面跟着MY_TYPE中的关键字private。这导致直接使用底部的构造函数被标记为错误,强制所有构造通过函数abe,您可以在其中包含断言或任意其他表达式。

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

关于ocaml - 类型定义中的断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33482515/

相关文章:

Python 断言与重复

c++ - 在 C++ 中实现断言检查的最佳方法是什么?

validation - 我如何为 @Assert\EqualTo 验证字段实体使用多个值

loops - OCaml 中退出循环的惯用异常

websocket - OCaml Websocket 示例

ocaml - OCaml在多态变体上的功能还不够多态吗?

ocaml - OCaml 中的整数构造函数

garbage-collection - 我可以将 OCaml GC 与 LLVM GC 接口(interface)一起使用吗?

ios - Crashlytics 是否遇到 assertionFailure 崩溃?

python - 单元测试 : Assert that a file/path exists