[코틀린쿡북] 4장. 함수형 프로그래밍

나고수·2021년 10월 14일
0

kotlin

목록 보기
7/10

4.1 알고리즘에서 fold 사용하기

fold 함수는 배열 또는 반복 가능한 컬렉션에 적용할 수 있는 축약 연산이다.
ex) fold를 사용해 정수의 합 계산하기
fun sum(vararg nums : Int) = nums.fold(0) {acc,n->acc+n}

초기값 0, acc는 누적값, n은 배열을 순서대로 순회하면서 얻는 값

IntArrayOf(3,1,4,1,5,9) 일때
acc = 0 , n = 3
acc = 3 , n = 1
acc = 4 , n = 4
acc = 8 , n = 1
acc = 9 , n = 5
acc = 14 , n = 9

4.2 reduce 함수를 사용해 축약하기

reduce함수는 fold함수와 매우 비슷하지만, 초기값을 따로 지정할 수 없고 배열(컬렉션)의 첫번째 값으로 고정된다는 것이 차이점이다.
따라서, 빈 배열(컬렉션) 즉, 첫번째 값이 없는 배열(컬렉션)에서는 사용 할 수 없다.

ex) 잘못 된 사용법 - 모든 배열의 수를 두배 한 다음 더하고 싶다.

fun solution(varags nums:Int)=nums.reduce(acc,i->acc+2*i)

IntArrayOf(3,1,4,1,5,9) 일때
acc = 3 , i = 2 
>> 첫번째 인자 3은 초기값으로 사용 되었기 때문에 두배가 되지 않는다.
acc = 5 , i= 8
acc = 13 , i = 2
acc = 15 , i = 10
acc = 25 , i = 18

4.3 꼬리재귀 적용하기

꼬리재귀는 자기자신함수를 다시 불러오는 재귀함수이다.
각각의 새로운 재귀 호출은 콜 스택에 프레임을 추가해서 메모리를 초과할 리스크가 생긴다. 하지만 꼬리재귀는 컴파일러에 의해 순회문으로 변환되어 작동된다. 따라서 콜 스택에 프레임을 추가하지 않고 메모리 측면에서 리스크가 줄어든다.

@JvmOverloads
tailrec fun factorial(n:Long,acc:BigInteger = BigInteger.ONE) :BigInteger =
when(n){
0L-> BigInterger.ONE
1L-> acc
else -> factorial(n-1,acc*BigInteger.valueOf(n))
}

trailrec 변경자를 적용할 수 있는 함수의 자격 요건

  • 해당 함수는 반드시 수행하는 마지막 연산으로서 자신을 호출해야한다.
  • try/catch/finally 블록 안에서는 꼬리재귀함수를 사용할 수 없다.
  • 오직 JVM 백엔드에서만 꼬리 재귀가 지원된다.
profile
되고싶다

0개의 댓글