📄
概念 📚 software-design-concepts

関数型プログラミング概念

純粋関数・不変性・副作用の分離・モナドなど関数型の考え方がもたらすコード品質の向上

関数型プログラミング(FP)は、プログラムを数学的な関数の合成として記述するパラダイムだ。オブジェクト指向との対立軸として語られることもあるが、現代では「関数型のコンセプトをオブジェクト指向言語で活用する」スタイルが実用的な選択として広まっている。JavaScriptやTypeScriptはマルチパラダイム言語であり、FPのコンセプトを部分的に採用しやすい。

純粋関数とは同じ入力に対して常に同じ出力を返し、副作用を持たない関数だ。参照透過性が保証されると、テストが容易になり、実行順序を気にせず合成できるようになる。不変性(Immutability)は状態の変化を追跡する必要をなくし、予期しない変更による不具合を防ぐ。JavaScriptではconstObject.freeze()・スプレッド演算子・immerライブラリなどを使って不変スタイルを実現できる。

副作用(DBアクセス・APIコール・ログ出力など)は必ず存在するが、純粋なロジックと副作用を発生させるコードを分離することで、ロジックのテスタビリティが格段に上がる。Option/Maybe・Either/Resultモナドはエラーや欠損値を型として表現し、null参照例外や例外フローの散在を防ぐ。関数合成とパイプライン演算子(|> またはRamdaのpipe/compose)は複数の変換を読みやすい形で連結する。

コードレビューで着目するポイント

  • ロジックと副作用が適切に分離されているか(コアのビジネスロジックに副作用が混入していないか)
  • 配列操作でmutable操作(push・splice等)を使っていないか(mapやfilterやreduceで代替できないか)
  • 共有された可変状態(shared mutable state)がないか
  • エラーをnull返しやthrowで処理する代わりにResult型で表現できないか
  • 複数の小関数を合成するかわりに、一つの大関数に手続きが詰め込まれていないか
  • anyやキャストを使わずに型安全なパイプラインを構築しているか
  • 副作用を閉じ込めるための構造(UseCase層・Adapter層等)が設計されているか

典型的なアンチパターン

副作用の隠蔽: 見た目が純粋な関数の内部でグローバル変数を書き換えたり外部APIを呼んだりする。呼び出し側がその副作用を知らないまま関数を合成するため、予期しない動作が生じる。

過度なモナド連鎖: EitherOptionのネストが3層4層になり、コードが元の命令型より難読化する。FPは手段であり目的ではなく、チームの習熟度に合わせた採用量が重要だ。

配列のin-place変更: Array.prototype.sort()がin-placeソートであることを忘れ、元の配列を意図せず変更する。FP的には[...arr].sort()と明示的にコピーする。

参考リソース

  • Kyle Simpson『Functional-Light JavaScript』(Leanpub)— JavaScript向けFP入門
  • Scott Wlaschin『Domain Modeling Made Functional』(The Pragmatic Bookshelf、2018)
  • fp-ts https://gcanti.github.io/fp-ts — TypeScriptのFPライブラリ
  • Effect-TS https://effect.website — 副作用管理・エラー処理・依存性注入を型安全に
  • Ramda https://ramdajs.com — 関数型スタイルのJavaScriptユーティリティ
  1. 1. 📄アーキテクチャスタイル
  2. 2. 📄ドメインモデリング
  3. 3. 📄モジュール分割と依存管理
  4. 4. 📄データモデリング
  5. 5. 📄API設計
  6. 6. 📄整合性とトランザクション
  7. 7. 📄非同期処理(Queue/Event)
  8. 8. 📄キャッシング
  9. 9. 📄ユーザーリサーチ
  10. 10. 📄情報アーキテクチャ
  11. 11. 📄インタラクションデザイン
  12. 12. 📄UX原則とヒューリスティクス
  13. 13. 📄アクセシビリティ(UX観点)
  14. 14. 📄UXメトリクス
  15. 15. 📄スケーラビリティ
  16. 16. 📄可用性とレジリエンス
  17. 17. 📄オブザーバビリティ
  18. 18. 📄環境・インフラ設計
  19. 19. 📄データマイグレーション
  20. 20. 📄セキュリティ設計原則
  21. 21. 📄データ保護とマルチテナント
  22. 22. 📄LLMセキュリティ
  23. 23. 📄ビジュアルデザイン原則
  24. 24. 📄デザインシステム
  25. 25. 📄コンポーネント設計
  26. 26. 📄スタイリング
  27. 27. 📄設計原則
  28. 28. 📄デザインパターン(GoF)
  29. 29. 📄エンタープライズパターン
  30. 30. 📄クリーンコード
  31. 31. 📄リファクタリング
  32. 32. 📄型設計とコントラクト
  33. 33. 📄関数型プログラミング概念
  34. 34. 📄エラーハンドリング
  35. 35. 📄テスト戦略と哲学
  36. 36. 📄テスト種別(機能テスト)
  37. 37. 📄テスト種別(UI・ビジュアル)
  38. 38. 📄テスト種別(契約・境界)
  39. 39. 📄並行処理・マルチスレッド
  40. 40. 📄パフォーマンス最適化
  41. 41. 📄ドキュメント管理
  42. 42. 📄バージョン管理と開発プロセス
  43. 43. 📄脅威モデリング
  44. 44. 📄通信保護(TLS)
  45. 45. 📄暗号化・機密情報管理
  46. 46. 📄認証・セッション管理
  47. 47. 📄認可・アクセス制御
  48. 48. 📄入力バリデーション
  49. 49. 📄インジェクション攻撃
  50. 50. 📄正規化(データベース正規化)