6
votes

Comment vérifier si deux valeurs sont créées avec le même constructeur?

disons que j'ai xxx

et je veux tester si les constructeurs de xx et yy sont égaux, Y a-t-il un moyen facile de faire ceci ? Au lieu d'avoir à xxx

qui devient assez désordonné quand de nombreux constructeurs sur un type


0 commentaires

3 Réponses :


8
votes

Vous pouvez réécrire ce qui précède à, un peu plus simple: xxx

mais je ne suis pas au courant d'une solution sans énumérer tous les constructeurs.


3 commentaires

Ceci est correct, bien que, il est souvent sage d'éviter _, _ et mieux à utiliser, (A _ | b _), _ . De cette manière, si le constructeur change, le compilateur peut vous aider à trouver des erreurs. Il y a une discussion sur cette discussion, Stackoverflow.com / Questions / 4346901 / ...


Il peut être fait en comparant les balises de valeurs (plutôt sûres avec les annotations de type appropriées) :)


@niucaroni: En effet, très bon point. J'ai pris la liberté pour l'intégrer à la réponse.



6
votes

Ceci est possible, en quelque sorte, via le module obj code>. Analyser les objets via les fonctions code> Obj code>, si cela est fait correctement, ne placez pas votre programme; Mais vous devez faire attention si vous voulez obtenir des résultats significatifs.

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


2 commentaires

Il s'agit d'un piratage de bas niveau un peu moche et très dépendant des détails de la mise en œuvre du compilateur. La solution ci-dessous est préférable.


@ Bezzlr La spécification de l'interface C garantit les propriétés de représentation que mon code repose sur. Donc, oui, c'est un piratage laids de bas niveau, mais ce qui dépend de la partie du comportement documenté de la mise en œuvre (uniquement).



4
votes

Une autre façon de faire cela peut bien fonctionner consiste à créer un autre type correspondant aux balises et utilisez ce type.

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


0 commentaires