← 一覧

関数型プログラミング

  • ちゃんと勉強したい
    • 数学における関数を意味する
    • JavaScriptにも関数型の特徴がある
    • Reactは関数型の影響を受けている
  • 関数型プログラミングは宣言型プログラミングという、より大きなパラダイムの一部
  • 計算のモデルの違い
    • 命令型
      • 計算とは命令を実行すること
      • チューリング機械
    • 関数型
      • 計算とは関数を呼び出して値を得ること
      • アロンゾ・チャーチ
    • 論理型
      • 計算とは証明を得ること

使いたい言語

Immutability

  • 不変性
  • 副作用がない
  • 変数の値を変えない
    • 0から99までの数値を出力するプログラム

    • 命令型の場合、変数iに値を保持し、状態を変更し、その結果を出力する

    • for(int i = 0; i < 100; i++) {
      	console.log(i);
      }
      
    • 関数型の場合、再帰を使い、iの状態は変更しない

    • function f(i) {
      	if(i > 99) {
      		return;
      	} else {
      		console.log(i);
      		return f(i+1);
      	}
      }
      f(0);
      

Referential Transparency

  • 参照透過性
  • 関数を値と置き換えても結果が変わらない
    • Date.now()は評価の度に異なる値が返ってくるので参照透過でない
    • purityとも近い概念
      • 同じ入力に対して同じ出力が返ってくる
      • 副作用がない
        • ファイル書き出しやエラー処理は副作用

Higher Order Functions

  • 高階関数
  • 関数を引数に取る関数
    • リストの中身を2乗したい場合

    • 命令型

    • function square(nums) {
      	let squared = [];
      	for(let i = 0; i < nums.length; i++) {
      		squared.push(nums[i] * nums[i]);
      	}
      	return squared;
      }
      
    • 関数型

    • function square(nums) {
      	return nums.map(function(n) { return n * n; });
      }
      

Lazy Evaluation

  • 遅延評価
  • 必要になるまで評価されない
    • Haskellは遅延評価がデフォルト
  • 対義語はEager Evaluation(先行評価)
    • 関数が呼ばれる度にif文が評価される
  • function myIf(condition, thenAction, elseAction) {
    	if(condition) {
    		thenAction();
    	} else {
    		elseAction();
    	}
    }
    

Lambda calculus

  • ラムダ計算
  • 関数型プログラミングの基礎
  • JavaScriptのアロー関数はラムダ計算の直接的な翻訳

JavaScriptでの使い所

1回だけ実行する

  • ボタンを1回だけ押せるようにしたい場合
    • グローバル変数でフラグを使う
    • 実行されたらイベントハンドラをnullにする
    • などが考えられるが、使い回せなかったり状態の管理が複雑になったりする
  • const once = (fn) => {
      let done = false;
      return (...args) => {
        if (!done) {
          done = true;
          return fn(...args);
        }
      }
    }
    
    const f = message => console.log(message);
    
    const doOnce = once(f);
    doOnce("hi!");
    doOnce("hi!");
    

数学の知識

  • Set Theory(集合論)
  • domain(定義域)とrange(値域)
    • 集合と写像
  • Category Theory(圏論)
    • 必須ではないが知っておくと理解の助けになる
    • モナドとかモノイドは圏論の概念
    • Haskellは圏論から多くのアイディアを受け取っている
    • Objects(対象)とMorphisms(射)
      • AとBが圏Cの対象であるとき、AからBへの射はABA \rightarrow Bと書く
      • 厳密には違うが、対象は集合で射は関数とみなせる

参考

技術