がnullでxない場合にのみ一連の関数を適用したいとしますx。
if (x !== null) x = a(x);
if (x !== null) x = b(x);
if (x !== null) x = c(x);
次に、同じことをする必要があるとしましょうy:
if (y !== null) y = a(y);
if (y !== null) y = b(y);
if (y !== null) y = c(y);
そして同じz:
if (z !== null) z = a(z);
if (z !== null) z = b(z);
if (z !== null) z = c(z);
適切な抽象化なしでわかるように、コードを何度も複製することになります。そのような抽象化はすでに存在しています:多分モナド。
たぶんモナドは値と計算コンテキストの両方を保持します。
- モナドは値を安全に保ち、それに関数を適用します。
- 計算コンテキストは、関数を適用する前のnullチェックです。
素朴な実装は次のようになります。
⚠️この実装は、説明のみを目的としています。これはそれを行う方法ではなく、多くのレベルで間違っています。しかし、これはあなたが私が話していることのより良い考えをあなたに与えるでしょう。
ご覧のとおり、何も壊れることはありません。
- 一連の関数を値に適用します
- いずれかの時点で値がnull(または未定義)になると、関数は適用されなくなります。
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>
付録1
これはこの投稿の目的ではないので、モナドが何であるかを説明することはできません。しかし、エリック・エリオットが過去のブログ記事で述べたように、JavaScriptモナドはシンプルになりました:
スキルレベルやカテゴリ理論の理解に関係なく、モナドを使用すると、コードを扱いやすくなります。モナドを利用しないと、コードの操作が困難になる可能性があります(たとえば、コールバック地獄、ネストされた条件付きブランチ、冗長性の向上)。
付録2
これが私がMaybeモナドを使ってあなたの問題を解決する方法ですmonetjs
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..catchステートメントを試してください。とはいえ、非常に異種の要素を含む配列は、設計上の問題のように見えます。