Imaginons que nous voulions appliquer une série de fonctions à xsi et seulement si xest non nul:
if (x !== null) x = a(x);
if (x !== null) x = b(x);
if (x !== null) x = c(x);
Disons maintenant que nous devons faire de même pour y:
if (y !== null) y = a(y);
if (y !== null) y = b(y);
if (y !== null) y = c(y);
Et la même chose pour z:
if (z !== null) z = a(z);
if (z !== null) z = b(z);
if (z !== null) z = c(z);
Comme vous pouvez le voir sans une abstraction appropriée, nous finirons par dupliquer le code encore et encore. Une telle abstraction existe déjà: la monade peut - être .
La monade Maybe contient à la fois une valeur et un contexte de calcul:
- La monade garde la valeur en sécurité et lui applique des fonctions.
- Le contexte de calcul est un contrôle nul avant d'appliquer une fonction.
Une implémentation naïve ressemblerait à ceci:
⚠️ Cette implémentation est à des fins d'illustration uniquement! Ce n'est pas ainsi que cela devrait être fait et cela est faux à plusieurs niveaux. Cependant, cela devrait vous donner une meilleure idée de ce dont je parle.
Comme vous pouvez le voir, rien ne peut casser:
- Nous appliquons une série de fonctions à notre valeur
- Si à tout moment la valeur devient nulle (ou indéfinie), nous n'appliquons plus aucune fonction.
const abc = obj =>
Maybe
.of(obj)
.map(o => o.a)
.map(o => o.b)
.map(o => o.c)
.value;
const values = [
{},
{a: {}},
{a: {b: {}}},
{a: {b: {c: 42}}}
];
console.log(
values.map(abc)
);
<script>
function Maybe(x) {
this.value = x; //-> container for our value
}
Maybe.of = x => new Maybe(x);
Maybe.prototype.map = function (fn) {
if (this.value == null) { //-> computational context
return this;
}
return Maybe.of(fn(this.value));
};
</script>
Annexe 1
Je ne peux pas expliquer ce que sont les monades car ce n'est pas le but de cet article et il y a des gens meilleurs que moi dans ce domaine. Cependant, comme Eric Elliot l'a dit dans le billet de blog de l'hist, JavaScript Monads Made Simple :
Quel que soit votre niveau de compétence ou votre compréhension de la théorie des catégories, l'utilisation de monades rend votre code plus facile à utiliser. Ne pas profiter des monades peut rendre votre code plus difficile à utiliser (par exemple, l'enfer des rappels, les branches conditionnelles imbriquées, plus de verbosité).
Annexe 2
Voici comment résoudre votre problème en utilisant la monade Maybe demonetjs
const prop = key => obj => Maybe.fromNull(obj[key]);
const abc = obj =>
Maybe
.fromNull(obj)
.flatMap(prop('a'))
.flatMap(prop('b'))
.flatMap(prop('c'))
.orSome('🌯')
const values = [
{},
{a: {}},
{a: {b: {}}},
{a: {b: {c: 42}}}
];
console.log(
values.map(abc)
);
<script src="https://www.unpkg.com/monet@0.9.0/dist/monet.js"></script>
<script>const {Maybe} = Monet;</script>
try..catchinstruction. Cela dit, un tableau contenant des éléments extrêmement hétérogènes me semble être un problème de conception.