How to check if two values ​​are created with the same constructor?

let's say that I have

type t = A of int | B of int

let xx = A(2);;
let yy = A(3);;

and I want to check if the xx and yy constructors are equal. Is there an easy way to do this? Instead of

match xx with
  A _ ->
  (match yy with A _ -> true | B _ -> false)
| B _ -> 
  (match yy with A _ -> false | B _ -> true);;

which gets pretty messy when there are many constructors like

+4
source share
3 answers

You can rewrite above, a little easier:

match xx, yy with
| A _, A _
| B _, B _ -> true
| (A _ | B _), _ -> false

but I don’t know the solution without listing all the constructors.

+7
source

It is possible, sort of, through the module Obj. Analysis of objects using functions Obj, if everything is done correctly, will not lead to the failure of your program; but you need to be careful if you want meaningful results.

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

( ) true, , false . equal_constructors ; true false, .

+5

, , - , , .

type t = A of int | B of int
module Tag = struct type t = A | B end

let to_tag = function A _ -> Tag.A | B _ -> Tag.B
let tags_are_equal x y =
    to_tag x = to_tag y
+4

Source: https://habr.com/ru/post/1017224/


All Articles