1
votes

Combinaison de deux cas de commutation dans reasonML

| (true, Select(true)) => true
| (false, Select(false)) => false
How can I combine these two in a switch statement with generic type?

5 commentaires

Je ne vois vraiment pas ce que vous demandez ici. Qu'entendez-vous par «combiner» et qu'entendez-vous par «générique»?


Au lieu d'écrire deux cas, existe-t-il un moyen d'écrire un cas tel que | (variantA, Select (VariantA)) => VariantA


Quel serait le but de cela? Si vous comparez avec la valeur que vous souhaitez extraire, cela signifie que vous l'avez déjà. A moins que je ne comprenne mal votre code, car il n'est pas vraiment valable bien sûr. Une explication plus détaillée serait utile.


@ a-c-sreedhar-reddy si la réponse que nous avons fournie dans Discord n'a pas fonctionné, veuillez nous en informer.


Postez la réponse! Si personne d'autre ne fait @ a-c-sreedhar-reddy, vous pouvez le faire aussi. Stackoverflow, c'est à chacun de trouver des réponses!


4 Réponses :


-1
votes

Oui, c'est faisable:

let theSolution = fun | (a, Select(b)) => a && b;
let theSolution = fun | (a, Select(b)) => a == b;

Par exemple:

"A is" true
"B is" false
"C is" true
"D is" false

Se traduira par:

type select = | Select(bool);

let a = (true, Select(true));
let b = (true, Select(false));
let c = (false, Select(true));
let d = (false, Select(false));

let theSolution = x => x |> fun | (_, Select(inside)) => inside;

Js.log2("A is", theSolution(a));
Js.log2("B is", theSolution(b));
Js.log2("C is", theSolution(c));
Js.log2("D is", theSolution(d));


2 commentaires

Mais (false, Select (true)) renverrait également true.


Il n'est pas clair d'après votre question que vous vouliez cela. Si vous voulez faire une logique booléenne à l'intérieur du commutateur, c'est possible: laissez theSolution = fun | (a, Sélectionnez (b)) => a && b; ou laissez theSolution = fun | (a, sélectionnez (b)) => a == b



-1
votes

Ce qui suit peut être une solution à votre problème. L'opération a && b dépend de la logique que vous voulez que le bloc suive. J'ai supposé raisonnablement que vous vouliez effectuer l'opération AND. Si vous fournissez d'autres conditions, cela peut être affiné.

let getSelectionResponse = x => switch(x){ | (a, Select(b)) => a&&b};


0 commentaires

1
votes

Malheureusement, les modèles que vous comparez dans une instruction switch doivent être 'linéaires' (c'est-à-dire que les variantes à l'intérieur des modèles ne doivent apparaître qu'une seule fois):

Voir https://caml.inria.fr/pub/docs/oreilly-book/html/book-ora016. html

Un motif doit nécessairement être linéaire, c'est-à-dire qu'aucune variable donnée ne peut apparaître plus d'une fois à l'intérieur du motif en cours de correspondance. Ainsi, nous aurions pu espérer pouvoir écrire:

# let equal c = match c with 
    (x,x) -> true   
  | (x,y) -> false;; Characters 35-36: This variable is bound several times in this matching

Mais cela aurait obligé le compilateur à savoir comment exécuter tests d'égalité. Pourtant, cela pose immédiatement de nombreux problèmes. Si nous accepter l'égalité physique entre les valeurs, on obtient un système qui l'est aussi faible, incapable de reconnaître l'égalité entre deux occurrences de la liste [1; 2], par exemple. Si nous décidons d'utiliser l'égalité structurelle, on court le risque d'avoir à traverser, à l'infini, circulaire structures.

Notez que ReasonML est juste une syntaxe alternative pour OCaml, donc ce qui précède vaut également pour Reason. match est simplement la version OCaml de switch.


0 commentaires

1
votes

Il est possible de combiner les deux cas de manière générique en utilisant un when guard:

let f = (a, b) =>
  switch (a, b) {
  | (a, Select(b)) when a == b => a
  };

Cependant, notez que ce n'est pas exhaustif, et vous ne l'avez pas spécifié ce qui doit être renvoyé dans le cas où a! = b . Pour éviter l'avertissement de non-exhaustivité et le plantage lors de l'exécution, vous devez ajouter un autre cas pour couvrir cela.


0 commentaires