JavaScript関数式プログラミング学習ノート:(一)入門


一.関数式プログラミングに関する概念
関数プログラミング
  • 概念:関数プログラミングは、オブジェクト指向プログラミングとプロセスプログラミングと並んでプログラミングされたモデルである.一般的には関数プログラミングは与えられた入力に対して、何回呼んでも同じ結果を返します.関数式プログラミングでは、関数はパイプです.これを一つの値に入れると、その先に新しい値が出てきます.他の役割はありません.
  • 特徴:
  • 関数は第一等公民です.他の基本的なデータの種類と同様に、パラメータが伝達されると変数に値が付与されます.
  • は、計算プロセスを多重化可能な関数に分解することを強調する
  • .
  • は純粋で、副作用のない関数だけが合格の関数です.つまり、純関数
  • です.
  • は一体どんなメリットがありますか?
  • コードはメンテナンスしやすいです.
  • 調整しやすい
  • ユニット試験
  • 純粋な関数
  • 概念:1つの関数の戻り結果はパラメータのみに依存し、実行中は副作用がなく、この関数を純粋関数と呼びます.
  • 例:
  •  const a = 1
     const foo = (b) => a + b
     foo(2) // => 3      foo()       ,         a   
    
    -  JS , toUpperCase(),slice()                .Math.random(), Date.now()    
    -        ? 
    
    副作用は,計算結果の過程において,システム状態の変化,あるいは外部世界との観測可能な相互作用である.例えば、ファイルシステムを変更してデータベースにレコードを挿入してhttpを送信して、可変データの取得を要求します.
  • はどうして純粋な関数を使うことを堅持しますか?
  • 可変性/自己文書化.純関数は完全自給自足であり、自身に依存する.
  • 高次関数
  • 概念:関数をパラメータとして用いることができ、または関数を戻り値の関数として用いることができる.
  •  const arr = [9, 5, 2, 7]
     const foo = function (x) {
       return x * x
     }
     const result = arr.map(foo)
     console.log(result)   // [ 81, 25, 4, 49 ]
    
    map、filter、reduce、sortなどの受信関数はパラメータの関数として実は高次関数です.
  • 引用
  • 高次関数アプリケーション–高次コンポーネントは、React
  • により多く適用されています.
  • の関数は一つのコンポーネントであり、Reactでよく取り上げられている高次コンポーネントも高次関数であり、入ってきたパラメータだけがReactコンポーネントになり、新しいコンポーネントに戻ります.2つの高次コンポーネントの形式:属性エージェント(props)と逆継承です.高次コンポーネントの主要機能はパッケージ化され、コンポーネントの汎用論理を分離し、汎用論理をコンポーネント間でより良く多重化します.高次コンポーネントのこの実現方法は、本質的には装飾者設計モードである.
  • 関数コリック化と合成
  • コリック化:関数の一部のパラメータだけに伝達して呼び出し、残りのパラメータを処理するための関数を返します.実はコリメートは高次関数の実現であり、すなわち低次関数を高次関数に変換して、一つの多パラメータの関数を単一パラメータ関数に変換することを期待している.
  • //     add(2,5) add(2)(5)   7?
    function add(x, y) {
      if (arguments.length === 1) {
        return function (z) { return x + z }
      } else {
        return x + y
      }
    }
    console.log(add(2)(5));   // 7
    console.log(add(2, 5));   // 7
    //    	       ,        
    function sum(x, y) {
     	 return x + y
    }
    function currySum(y) {
    	  return function (x) {
    	    return x + y
    	  }
    }
    console.log(sum(1, 2))         // 3
    console.log(currySum(2)(1))    // 3
    
  • コリック化の「プリロード」能力は、2つのパラメータ呼び出し関数に伝達することによって、これらのパラメータを記憶した新しい関数を得ることができる.ある意味では、これはパラメータの多重化
  • である.
    let checkage = min => (age => age > min);
    let checkage18 = checkage(18);
    checkage18(20);	// =>true
    
  • 関数の合成(compose):一つの値が複数の関数を経て、他の値になる場合、すべての中間ステップを一つの関数に統合することができます.これを「関数の合成」といいます.より良い独立性
    //        (x + 3) * 3
    function add(x) {
      	return x + 3
    }
    function multiply(x) {
     	 return x * 3
    }
    let result = multiply(add(2))
    console.log(result)   // 15
    //   
    function compose(f, g) {
    	  return function (x) {
    	    return f(g(x))
    	  }
    }
    let composeFoo = compose(multiply, add)
    console.log(composeFoo(2))  // 15
    
    補足:完全なコリ化と合成ツール関数はlodashツールライブラリを参照してください.https://www.lodashjs.com/
    命令式と宣言式
  • 命令式コード:「マシン」にどうやって仕事をするかを命令します.これはあなたが望むものであれ、あなたの命令に従います.
  • ステートメントコード:マシンに何がほしいかを教えて、マシンにどうやって作るかを考えさせます.命令式とは違って、宣言式は一歩の指示ではなく、表現を書くことを意味します.日常の符号化の習慣は声明式
  • です.
    //    
    const makes = [];
    for (let i = 0; i < cars.length; i++) {
      	makes.push(cars[i].make);
    }
    //    
    let makes = cars.map(car => car.make);
    
    手紙(Funtor)
  • は通信子を理解しています.まず一つのカテゴリーです.つまり、値と変形関係が含まれている容器です.特に変形関係は各値に順次作用し、現在の容器を別の容器に形成することができる.
  • map法を有するいかなるデータ構造も通信子として実現できる.
    class Functor {
    	  constructor(val) { 
    	    this.val = val; 
    	  }
    
    	  map(f) {
    	    return new Functor(f(this.val));
    	  }
    }
    //    new   ,          ,     of  ,        。
    Functor.of = function(val) {
      	return new Functor(val);
    };
    
    二.Monad通信子とPromise
    Monad手紙
  • 通信器は一つの容器であり、どの値も含まれています.手紙の中にもう一つの手紙を含めるのも完全に合法です.しかし、こうすると何重もの入れ子ができます.
  • Monad通信子の役割は、いつも単一層の通信を返すことです.flatMapの方法があります.mapの方法と同じです.唯一の違いは、入れ子を生成したら、後者の内部の値を取り出します.戻るのは永遠に単層の容器で、入れ子が発生しないようにします.
  • class Monad extends Functor {
    	  join() {
    	    return this.val;
    	  }
    	  flatMap(f) {
    	    return this.map(f).join();
    	  }
    }
    
    Promise
  • Promiseは、幾重にもネストされているコールバック地獄
  • を解決するために使用される.
  • ResoveのPromiseの度に、私たちは二つの状況を判断する必要があります.Resoliveの内容がまだPromiseであれば、ResoliveというPromiseに再帰します.Resoliveの内容がPromiseでない場合、内容の具体的な状況(対象、関数、基本タイプなど)によって、fulfillまたはreject現在Promiseに行きます.
  • Monad通信子のflatMapの能力は、コンテナを何重にも分解して、直接に一番奥に入っている値を取り出すことができます.ここにある容器はPromiseを指します.flatMapにはもう一つの名前があります.
  • は正確な言い方は何もありません.Promiseの実現はMonad通信子です.再帰思想が似ているだけで、学習と比較してみます.
    三.関数式プログラミングJSでの他のアプリケーション
  • クローズド
  • 各種API方法
  • 追加する必要があります.
    四.まとめと参考リンク
  • 関数の外部状態への依存は、システムの複雑性が大幅に向上した主な原因であり、関数をできるだけピュアにし、システムの複雑度をさらに低下させる.もちろん、すべてのデータは変えられないものであり、実行リソースのカートンを占拠するなど、深刻な問題を引き起こすこともある.学習中、多くの人が「銀弾がない」という概念に言及しているのを見た.ソフトウェア開発の過程では万能な終殺兵器がないと説明するために、各種の方法を総合的に運用してこそ解決の道です.
  • 補足すべきいくつかの点:最終再帰最適化、不活性性求値、pointfree、Appplicative、他の通信子
  • 参照リンク:
  • http://www.ruanyifeng.com/blog/2017/02/fp-tutorial.html 阮一峰ブログ関数式プログラミング入門教程
  • https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/JS関数式プログラミングガイド
  • https://www.ibm.com/developerworks/cn/java/j-lo-funinscala3/index.html#icomments 関数は一等公民になりました.
  • http://ewind.us/2017/promise-implementing/ソースコードからPromise概念を見て
  • を実現します.
  • https://juejin.im/post/5a5300b4518825732d7f6ff0 回調地獄から自通信子の半群まで:熟知していて見知らぬMonad
  • を解読します.
  • https://www.cnblogs.com/tjyoung/p/8976013.html JavaScript関数プログラミング