| (true, Select(true)) => true | (false, Select(false)) => false How can I combine these two in a switch statement with generic type?
4 Réponses :
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));
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
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};
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 matchingMais 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
.
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.
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!