如何检查是否使用相同的构造函数创建了两个值?

rom*_*run 5 ocaml

让我说我有

type t = A of int | B of int

let xx = A(2);;
let yy = A(3);;
Run Code Online (Sandbox Code Playgroud)

我想测试xx和yy的构造函数是否相等,有没有一种简单的方法可以做到这一点?而不是必须

match xx with
  A _ ->
  (match yy with A _ -> true | B _ -> false)
| B _ -> 
  (match yy with A _ -> false | B _ -> true);;
Run Code Online (Sandbox Code Playgroud)

当一个类型上有许多构造函数时会变得非常混乱

ako*_*ski 8

你可以重写上面的内容,有点简单:

match xx, yy with
| A _, A _
| B _, B _ -> true
| (A _ | B _), _ -> false
Run Code Online (Sandbox Code Playgroud)

但是我不知道没有列举所有构造函数的解决方案.

  • 这是正确的,但通常明智的做法是避免使用`_,_`和更好地使用`(A _ | B _),_`.这样,如果构造函数更改,编译器可以帮助您查找错误.有一个讨论,http://stackoverflow.com/questions/4346901/suggestion-for-solving-fragile-pattern-matching (3认同)

Gil*_*il' 6

这是可能的,通过Obj模块.通过Obj函数分析对象,如果操作正确,不会导致程序崩溃; 但如果你想获得有意义的结果,你需要小心.

let equal_constructors (x : 'a) (y : 'a) =
  let r = Obj.repr x and s = Obj.repr y in
  if Obj.is_int r && Obj.is_int s then (Obj.obj r : int) = (Obj.obj s : int) else
  if Obj.is_block r && Obj.is_block s then Obj.tag r = Obj.tag s else
  false
Run Code Online (Sandbox Code Playgroud)

当调用变量类型的值(不是多态变体类型)时,true如果两个值都具有相同的零参数构造函数或者两者都具有相同的1或更多参数构造函数,则此函数返回,false否则返回.类型系统不会阻止你equal_constructors在其他类型实例化; 你会得到一个truefalse返回值,但不一定是有意义的.

  • @yzzlr C接口的规范保证了我的代码所依赖的表示属性.所以,是的,这是一个丑陋的低级黑客攻击,但它依赖的是(仅)实现的记录行为的一部分. (3认同)