JavaScriptで「Maybe」検出器を構築しようとします.


翻訳原文の出所:Buiding a Maybe in JavaScript拙者の翻訳は少し違っています.笑わないでください.
Uncaugt TypeError:Canot read property'x'of undefined(未定義の属性「x」は読めません)に遭遇することが多いです.もしあなたがこれを見たら、以前は単に触っただけでなく、目に見えるものだけを見たら、ディスプレイを壊したいと思った瞬間があります.ここで私たちが尊敬するコンピュータ分野のジャズ、トニー・ホールを思い出しました.Infoqで行われた大会の演説で彼が使ったテーマは「Null References:The Billion Dolar Mistake」(Null引用:10億ドル級のエラー)で、講演の要約には「Nullを引用して自分の10億ドルの誤りと言います.その発明は1965年で、その時は言語対象(ALGOW)を使っていました.最初の全面的な引用型システムを設計しました.私の目的はすべての引用が絶対安全であることを確保することです.コンパイラは自動的に検査を行います.しかし、誘惑に耐えられず、Null引用に加入しました.実現しやすいだけです.数え切れないほどのエラー、バグ、システム崩壊を引き起こしました.その後40年間で10億ドルの損失を引き起こしたかもしれません.損失です.ここ数年、マイクロソフトのPREfixやPREfastなど、さまざまなプログラムを使って、引用をチェックしています.Nullではないリスクがある場合は警告しています.更新されたプログラム設計言語は、Spec gaはすでにNullではない引用の声明を導入しています.これは1965年に拒否された解決策です.
10億ドル級のエラー
幸いにも、機能的なプログラミング技術を使って、清潔で簡潔で信頼できる方法で痛みを和らげられます.以下のオブジェクトから属性「c」の値を抽出し、文字列「is great」を付加することを想像してみましょう.
const a = {
    b: {
        c: "fp"
    }
};
私たちが使っている簡単な方法は、次のようなものかもしれません.
const appendString = (obj) =>
    obj.b.c + " is great";
    
appendString(a);
このような書き方は素晴らしいですが、悲しいことにaオブジェクトは同じではないです.したがって、私たちが回収したデータは時に以下のような形になります.
const a = {
    b: {}
};

// or

const a = {};
この時、私たちはapendString関数を呼び出した時、全宇宙は爆発します.
未定義の属性「c」を読めませんでした.
この時は関数の参照を空でチェックします.
const appendString = (obj) => {
    if (!obj || !obj.b || !obj.b.c || !) return null;
    return obj.b.c + " is great";
}
これは有効ですが、醜くて間違えやすいです.私たちはそれぞれのタイプのオブジェクトに対して特定の(正しい)空検査を定義しなければならない.これは面白い(複雑)ではないか.ハハハ、この時はMaybeが出場します.Maybeの基本的な使い方
基本的に、私たちは構築する対象をカプセル化します.その値はnullの概念であり、その後の複雑さを考慮します.Elm(一つはWebフロントエンドの純関数言語に集中する)を学習した後、Maybeには二つの概念状態Maybe.justMaybe.nothingが実装されています.初心者に対しては、ブール値を返すisNothing方法を簡単に定義し、Maybeには何も含まれていないかを教えてくれます.
const isNullOrUndef = (value) => value === null || typeof value === "undefined";

const maybe = (value) => ({
    isNothing: () => isNullOrUndef(value)
});
また、簡単な工場関数を使用して、Maybeを作成します.これからもっと多くの方法を追加するかもしれないと考えて、オブジェクトを使用して定義します.
const Maybe = {
    just: maybe,
    nothing: () => maybe(null)
};
だから今はこうしてもいいです.
const maybeNumberOne = Maybe.just("a value");
const maybeNumberTwo = Maybe.nothing();

maybeNumberOne.isNothing(); // false
maybeNumberTwo.isNothing(); // true
すべてはいいですが、まだ実用的ではありません.プログラムはデータの変換に関するもので、Maybeの関数を変更する方法が必要です.このmap関数は、変換を希望する関数パラメータを使用して、変換結果を含む新しいパラメータを返します.重要なことに、mapがコンテンツを含まない場合、関数は適用されなくなり、新しいmaybe方法に戻ります.
const maybe = (value) => ({
    isNothing: () => isNullOrUndef(value),
    map: (transformer) => !isNullOrUndef(value) ? Maybe.just(transformer(value)) : Maybe.nothing()
});
このようにして、maybe.nothingを呼び出すことができます.
const maybeOne = Maybe.just(5);
maybeOne.map(x => x + 1); // Maybe.just(6);

const maybeTwo = Maybe.nothing();
maybeTwo.map(x => x + 1) // Maybe.nothing();
重要な点はmaybeが新しいmaybe.mapを返すので、これらの操作をリンクしてもいいです.私たちが今できる最初の問題に戻ります.
const a = {
    b: {
        c: "fp"
    }
};

const maybeA = Maybe.just(a)
    .map(a => a.b)
    .map(b => b.c)
    .map(c => c + " is great!");
ここの利点は、チェーン内の任意のステップがnullに戻ると、まだ結果Mayboe.nothingの結果が得られます.実行時のエラーではありません.
はい、maybeの上にGithubライブラリがあります.A Maybone montination in JavaScript:
それはmaybe.jsの実装よりも柔軟であり、JavaScriptのタイプのシステム制限と言語の一般的な柔軟性を考慮した追加の機能を付け加えている.
Point-freeチェーン関数
以前発表した文章のカーリー関数を見たら、これよりもっと上手にできると思います.オブジェクトから命名属性を抽出する高次関数を作成し、文字列を追加できます.
const prop = (propName) => (obj) => obj[propName];
const append = (appendee) => (appendix) = appendee + appendix;
ここでは、上のJavaScript関数式プログラミング(一)の中の知識点を参照することができます.
したがって、今はHaskellチェーンでこの機能を使用できます.
const a = {
    b: {
        c: "fp"
    }
};

const maybeA = Maybe.just(a)
    .map(prop("b"))
    .map(prop("c"))
    .map(append(" is great!"));
はい、私達は今やっとこのステップに着きました.空の検査を処理し、map形式に再構成しました.次に必要なのはロジックの再利用性です.私たちが望むのは、私たちの機能を一つの機能に伝達し、すべてのステップを適用して、多くの異なるpoint-free上でピックアップを再利用することができるようにすることです.
   const extractor = // what we're about to make
    extractor(Maybe.just(a)); // Maybe.just("fp is great")
必要なのは私たちのステップの関数であり、各ステップはMaybe方法を順次呼び出す.関数Maybe.mapを呼び出します.
const Maybe = {
    just: maybe,
    nothing: () => maybe(null),
    chain: (...fns) => (input) => fns.reduce((output, curr) => output.map(curr), input)
};
私たちは今、Maybe.chainに適用できる利用可能な機能を構築することができる.
const appendToC = Maybe.chain(
    prop("b"),
    prop("c"),
    append(" is great!")
);
様々な入力に使用します.
const goodInput = Maybe.just({
    b: {
        c: "fp"
    }
});

const badInput = Maybe.just({});

appendToC(goodInput); // Maybe.just("fp is great!")
appendToC(badInput); // Maybe.nothing()
maybeを勉強する前に、Elmの価値観概念に慣れませんでしたが、彼らはJavaScriptの中で遅れたくないです.私たちは簡単にそれを使うと、基本的な方法しか使えません.ですから、その基礎にもっと多くの機能関数を追加したいです.ですから、後でMaybeを使った後続の文章を読みます.
:完了:
もっと読む
  • Elm入門実践(一)——基礎編
  • 関数式プログラミング入門教程
  • JavaScript関数プログラミング(一)
  • JavaScript関数プログラミング(二)
  • JavaScript関数プログラミング(3)
  • 関数JavaScript(2):関数式プログラミング言語はどうやって作りますか?
  • A Maybone moad implemention in JavaScript
  • Fnctional Programeming in Javascript