본문으로 바로가기

함수형 프로그래밍이란 순수 함수선언형 프로그래밍을 기반으로 함수 조합 및 모나드 조합으로 코드를 설계, 구현하는 기법입니다. 

 

순수 함수 : https://darrengwon.tistory.com/595?category=905593

선언형 프로그래밍 : https://darrengwon.tistory.com/761?category=905593

 

함수형 프로그래밍 언어는 정적 타입, 자동 메모리 관리, 계산법, 타입 추론, 일등 함수를 기반으로 대수 데이터 타입, 패턴 매칭, 모나드, 고차 타입 등의 기능을 제공합니다. 그러나 함수형 프로그래밍의 속성을 구현하기 위한 기능을 모든 프로그래밍 언어가 지원하는 것도 아니고, 대부분은 절차형 프로그래밍과 함수형 프로그래밍을 섞어 쓰게 됩니다.

 

 

제네릭 함수

 

TS에서 함수 조합을 하기 위해서는 어떤 타입에도 대응하도록 타입을 지정해야 하므로 제네릭을 사용해야 합니다.

function test<T>(arg: T): void {
  console.log(arg);
}

function doubleGeneric<T, Q>(arg1: T, arg2: Q): void {
  console.log(arg1, arg2);
}

// 타입에 연연하지 않고 사용할 수 있음
test("hello");
test(3);
test(true);
test({ name: "da", age: 23 });

doubleGeneric("hello", 3);
doubleGeneric(true, { name: "da", age: 23 });

 

 

고차 함수 (high order function)

 

전에 고차 컴포넌트와 함께 고차 함수의 개념을 다룬 적이 있습니다.

https://darrengwon.tistory.com/756?category=867626

 

수학적으로 쉽게 설명하면 합성 함수입니다. 함수의 결과값이 다른 함수의 매개변수로 들어갈 수 있다는 간단한 아이디어입니다. 

x ~> f ~> g ~> h ~> y

y = h(g(f(x)))

 

다음과 같이 커링으로 사용할 수 있습니다.

커링 : https://darrengwon.tistory.com/738?category=905593

type FirstOrderFunc<T, R> = (T) => R;
type SecondOrderFunc<T, R> = (T) => FirstOrderFunc<T, R>;
type ThridOrderFunc<T, R> = (T) => SecondOrderFunc<T, R>;

const inc: FirstOrderFunc<number, number> = (x) => x + 1;
const add: SecondOrderFunc<number, number> = (x) => (y) => x + y;
const add3: ThridOrderFunc<number, number> = (x) => (y) => (z) => x + y + z;

console.log(inc(1));
console.log(add(3)(4));
console.log(add3(1)(2)(3));

 

고차 함수를 호출 연산자 모두 쓸 필요 없이 덜 사용해서 부분 적용 함수를 사용할 수도 있습니다.

const partialFunc = add3(1)(2);
console.log(partialFunc(3));

 

 

클로저

 

과거 https://darrengwon.tistory.com/633 에 정리한 바에 따르면 클로저는 외부 함수가 사라졌음에도 내부 함수가 외부 함수에서 정의한 변수를 사용할 수 있다는 것입니다. 이를 '지속되는 유효 범위'(persistence scope)라고 합니다.

 

function add(x) {

  // 내부 함수에서 외부 함수의 x에 접근할 수 있습니다.
  return function add2(y) {
    return x + y;
  };
}

console.log(add(2)(3));

 

함수 조합

 

작은 함수를 조합하여 하나의 기능을 하는 또 다른 함수를 조합해내는 것을 말합니다. compose와 pipe라는 이름의 메서드가 관습적으로 사용됩니다. compose(f, g, h)는 f(g(h(x))) 순서지만 pipe(f, g, h)는 h(g(f(x))) 순서로 실행합니다.

 

함수를 합치는 compose 함수를 작성해보았습니다. (ramda 등 다른 FP 패키지를 통해 compose를 할 수 있습니다만 연습하는 느낌으로 구현해봅시다)

const compose = (...functions: readonly Function[]) => (x) => {
  const deepCopiedFunctions = [...functions];
  return deepCopiedFunctions.reverse().reduce((value, func) => func(value), x);
};

const inc = (x) => x + 1;

const composedAdd = compose(inc, inc, inc);

// inc(inc(inc(1)))
console.log(composedAdd(1)); // 4

 

 

 

 

 

 

참고한 글, 좋은 글)

 

 

함수형 프로그래밍 언어에 대한 고찰 - LINE ENGINEERING

안녕하세요, LINE에서 게임 플랫폼을 개발하는 주니어 개발자 김부성, 이재호입니다. 저희는 LINE Game Cloud가 함수형 프로그래밍 언어 중 하나인 Clojure로 구현되어 있는 것을 보고 함수형 프로그래�

engineering.linecorp.com

 

(번역) 어떤 프로그래밍 언어들이 함수형인가?

이 글은 Kris Jenkins(@krisjenkins)의 “Which Programming Languages Are Functional?”을 허락을 구해 번역한 것입니다. (@bradlee 님의 번역도 있습니다.)

medium.com

 

함수형 프로그래밍과 현실

함수형 프로그래밍이 좋다는 소문은 익히 듣고 있습니다. 그런데 대체 왜 좋은 건지 잘 이해가 되지는 않지요. 막연히, 함수형 프로그래밍을 배워가며 노력하다보면 나도 체감할 수 있으리라는

medium.com

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체