Skip to content
Grok

Functional Programming

แนวคิดหลัก

Pure Functions: ฟังก์ชันที่ไม่มีผลข้างเคียง (side effects) และให้ผลลัพธ์เดียวกันเสมอเมื่อรับอินพุตเดียวกัน

ts
// Pure function
const add = (a: number, b: number): number => a + b;

// Impure function (has side effect)
let total = 0;
const addToTotal = (value: number): number => {
  total += value; // modifies external state
  return total;
};

Immutability: ข้อมูลไม่สามารถเปลี่ยนแปลงได้หลังจากสร้างขึ้น ต้องสร้างข้อมูลใหม่แทนการแก้ไข

ts
// Immutable approach
const originalArray: number[] = [1, 2, 3];
const newArray: number[] = [...originalArray, 4]; // creates new array

// Mutable approach (avoid in functional programming)
const array: number[] = [1, 2, 3];
array.push(4); // modifies original array

Higher-Order Functions: ฟังก์ชันที่รับฟังก์ชันเป็นอาร์กิวเมนต์หรือคืนค่าเป็นฟังก์ชัน

ts
// Function that takes a function as argument
const map = <T, U>(array: T[], fn: (item: T) => U): U[] => array.map(fn);
const double = (x: number): number => x * 2;
console.log(map([1, 2, 3], double)); // [2, 4, 6]

// Function that returns a function
const multiply = (x: number) => (y: number): number => x * y;
const triple = multiply(3);
console.log(triple(4)); // 12

Function Composition: การรวมฟังก์ชันหลายตัวเข้าด้วยกันเพื่อสร้างฟังก์ชันใหม่

ts
// Simple composition
const compose = <T, U, V>(f: (x: U) => V, g: (x: T) => U) => (x: T): V =>
  f(g(x));

const addOne = (x: number): number => x + 1;
const double = (x: number): number => x * 2;

const addOneThenDouble = compose(double, addOne);
console.log(addOneThenDouble(3)); // 8 (3 + 1 = 4, then 4 * 2 = 8)

// More flexible composition with reduce
const pipe = <T>(...fns: Array<(x: T) => T>) => (x: T): T =>
  fns.reduce((acc, fn) => fn(acc), x);

const add = (a: number, b: number): number => a + b;
const square = (x: number): number => x * x;

const addThenSquare = pipe(
  (x: number) => add(x, 5), // Add 5
  square, // Then square the result
  x => x / 2, // Then divide by 2
);

console.log(addThenSquare(5)); // 50 ((5 + 5)² / 2 = 100 / 2 = 50)

Recursion: การเรียกฟังก์ชันตัวเองซ้ำๆ แทนการใช้ลูป

ts
// Recursive factorial
const factorial = (n: number): number => {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
};

console.log(factorial(5)); // 120

// แบบใช้ลูป (ไม่ใช่ functional style)
const factorialImperative = (n: number): number => {
  let result = 1;
  for (let i = 2; i <= n; i++) {
    result *= i;
  }
  return result;
};

// ตัวอย่างการใช้งาน Tail Recursion
const factorialTailRec = (n: number, accumulator: number = 1): number => {
  if (n <= 1) return accumulator;
  return factorialTailRec(n - 1, n * accumulator);
};

console.log(factorialTailRec(5)); // 120

เหมาะสำหรับ

  • การประมวลผลข้อมูลแบบขนาน (Parallel Processing)
  • การจัดการกับโครงสร้างข้อมูลขนาดใหญ่
  • ระบบที่ต้องการความน่าเชื่อถือและทดสอบง่าย
  • การพัฒนาซอฟต์แวร์ที่ซับซ้อนและต้องการบำรุงรักษาในระยะยาว
  • ระบบที่ต้องการความปลอดภัยสูงและลดข้อผิดพลาด