Supposons que j'aie deux types, Vector2D
et Vector3D
et qu'ils soient étiquetés (c'est le terme correct, non ?), et je veux écrire une fonction qui opère UNIQUEMENT sur Vector2D
(ou est-ce que vector(two)
est plus correct ici ?), comme ceci :
type two;
type three;
type vector('a) =
| Vector2D(float, float): vector(two)
| Vector3D(float, float, float): vector(three);
let first = (a: vector(two)) => {
switch(a) {
| (x, y) => x +. y
}
}
let second = (Vector2D(x, y)) => {
x +. y
}
let third = ((x, y): vector(two)) => {
x +.y
}
Les fonctions first
et second
interdisent de passer un Vector3D
, comme je le souhaite, mais elles soulèvent un avertissement "Ce pattern matching n'est pas exhaustif".
Pour first
, j'aimerais savoir pourquoi ce n'est pas exhaustif, n'ai-je pas limité les options possibles à Vector2D
ici ? Pour second
, je suppose que la raison est la même que pour first
, mais comment serait-il même possible de résoudre le problème avec cette syntaxe ?
Quant à third
, celui-ci ne compile pas parce que "Ce pattern correspond à ('a, 'b) mais vector(two) était attendu". Pourquoi le compilateur s'attend-il à un tuple ici ? N'est-il pas possible d'utiliser la destructuration dans les paramètres de fonction ?
ÉDIT :
Il s'avère qu'il y a un problème encore plus simple pour démontrer ce que je veux
type state = Solid | Liquid
let splash = (object) => {
switch(object) {
| Liquid => "bruits d'éclaboussures. Je suppose."
| Solid => "" // cela ne devrait même pas être possible dans le contexte de cette fonction, et je veux que le compilateur l'applique
}