🔥 연습문제 - 피보나치 수열

330자
5분

함수형 프로그래밍에서는 클로저(Closure)라는 개념이 자주 등장해요. 클로저는 함수 내부에 상태를 가지고 있는 함수를 말하는데요. 이번에는 클로저를 활용하여 피보나치 수열을 반환하는 함수를 만들어 볼 거예요.

피보나치 수열은 0과 1로 시작하며, 다음 수는 바로 앞의 두 수의 합이 되는 수열이에요. 예를 들어 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ... 와 같은 식으로 나타낼 수 있죠.

Go 언어에서는 다음과 같이 클로저를 사용하여 피보나치 수열을 반환하는 함수를 구현할 수 있어요.

go
package main
 
import "fmt"
 
// fibonacci는 피보나치 수열을 반환하는 함수를 반환하는 함수예요.
func fibonacci() func() int {
    // 피보나치 수열의 첫 번째와 두 번째 값을 초기화해요.
    a, b := 0, 1
 
    // 익명 함수를 반환해요.
    return func() int {
        // 현재 피보나치 수열의 값을 저장할 변수를 선언해요.
        curr := a
        // 다음 피보나치 수열의 값을 계산해요.
        a, b = b, a+b
        // 현재 피보나치 수열의 값을 반환해요.
        return curr
    }
}
 
func main() {
    // 피보나치 수열을 반환하는 함수를 호출해요.
    f := fibonacci()
    // 피보나치 수열의 첫 10개 값을 출력해요.
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}
 
go
package main
 
import "fmt"
 
// fibonacci는 피보나치 수열을 반환하는 함수를 반환하는 함수예요.
func fibonacci() func() int {
    // 피보나치 수열의 첫 번째와 두 번째 값을 초기화해요.
    a, b := 0, 1
 
    // 익명 함수를 반환해요.
    return func() int {
        // 현재 피보나치 수열의 값을 저장할 변수를 선언해요.
        curr := a
        // 다음 피보나치 수열의 값을 계산해요.
        a, b = b, a+b
        // 현재 피보나치 수열의 값을 반환해요.
        return curr
    }
}
 
func main() {
    // 피보나치 수열을 반환하는 함수를 호출해요.
    f := fibonacci()
    // 피보나치 수열의 첫 10개 값을 출력해요.
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}
 

위 코드에서 fibonacci 함수는 피보나치 수열을 반환하는 클로저 함수를 반환해요. 클로저 함수 내부에서는 ab 변수를 사용하여 피보나치 수열의 값을 계산하고 있어요.

main 함수에서는 fibonacci 함수를 호출하여 피보나치 수열을 반환하는 클로저 함수를 얻어요. 그리고 for 루프를 사용하여 피보나치 수열의 첫 10개 값을 출력하고 있죠.

위 코드를 실행하면 다음과 같은 결과를 얻을 수 있어요.

text
0
1
1
2
3
5
8
13
21
34
text
0
1
1
2
3
5
8
13
21
34

이렇게 클로저를 사용하면 함수 내부에 상태를 가지고 있는 함수를 만들 수 있어요. 피보나치 수열을 반환하는 함수 외에도 다양한 용도로 클로저를 활용할 수 있답니다.

lecture image

위 다이어그램은 fibonacci 함수가 동작하는 과정을 나타내고 있어요. fibonacci 함수를 호출하면 클로저 함수가 반환되고, 클로저 함수 내부에서는 ab 변수를 초기화한 후 익명 함수를 반환하죠. 익명 함수에서는 현재 피보나치 수열의 값을 저장하고, 다음 피보나치 수열의 값을 계산한 후 현재 피보나치 수열의 값을 반환하고 있어요.

클로저를 활용하면 이렇게 함수 내부에 상태를 가지고 있는 함수를 만들 수 있답니다. 앞으로도 클로저를 활용하여 다양한 문제를 해결해 보면 좋겠죠?

YouTube 영상

채널 보기
Maybe 펑터와 타입 들어올리기 | 프로그래머를 위한 카테고리 이론
리더 펑터 - 함수도 펑터다! | 프로그래머를 위한 카테고리 이론
미들웨어 적용과 라우팅 | NestJS 가이드
앨런 튜링이 들려주는 튜링 테스트와 보편 기계 이야기
함수형 미들웨어 | NestJS 가이드
펑터 법칙과 등식 추론 | 프로그래머를 위한 카테고리 이론
Product와 Coproduct가 Bifunctor인 이유 | 프로그래머를 위한 카테고리 이론
List 펑터 - 왜 map은 for 루프보다 강력한가? | 프로그래머를 위한 카테고리 이론