순수함수와 일급 객체 함수

부수효과(Side Effect)

// 순수 함수
fun add(a: Int, b: Int): Int = a + b // 동일한 입력에 동일한 출력 반환

// 순수 함수가 아님
var counter = 0
fun increment(): Int {
    counter += 1 // side effect
    return counter
}

일급 객체 함수 처리

fun main() {
    println(add1(10, 20))
    println(add2(1, 2))
    println(highFunc({ x: Int, y: Int -> x * y }, 100, 100))
    val rf = returnFunc()
    println(rf(3, 5))

		// 일급 함수를 자료구조에 저장
    val map = mutableMapOf<String, (Int, Int) -> Int>()
    map["add"] = ::add
    map["mul"] = ::mul

    val operator = "*"
    when(operator) {
        "+" -> println(map["add"]?.invoke(10, 20))
        "*" -> println(map["mul"]?.invoke(10, 20)) // 200
        else -> println("없음")
    }
}

val add1 = fun (x: Int, y: Int): Int = x + y // 익명 함수 변수에 할당
val add2 = { x: Int, y: Int -> x + y } // 람다를 변수에 할당
fun highFunc(sum: (Int, Int) -> Int, a: Int, b: Int): Int = sum(a, b) // 함수의 인자로 전달
fun returnFunc(): (Int, Int) -> Int = { x: Int, y: Int -> x + y } // 반환 타입을 람다로 반환

fun add(a: Int, b: Int): Int = a + b
fun mul(a: Int, b: Int): Int = a * b

실행결과
30
3
10000
8
200

커링(Currying Function)함수 알아보기

// fun add(x: Int, y: Int): Int = x + y add 함수를 커링함수로 바꿈.

fun main() {
    val add2 = addCurried(2)
    println(add2)
    val result = add2(3)
    println(result)
}

fun addCurried(x: Int): (Int) -> Int {
    return fun(y: Int): Int {
        return x + y
    }
}

실행결과
(kotlin.Int) -> kotlin.Int
5

메서드 체인처리

class Person(var name: String, var age: Int) {
    fun introduce() { println("Hello, I'm $name and I'm $age years old.") }
    
    fun changeAge(newAge: Int): Person {
        this.age = newAge
        return this
    }
}

// 확장 함수로도 정의 가능
fun Person.changeName(newName: String): Person {
    this.name = newName
    return this
}

fun main() {
    val john = Person("John", 25)
        .changeName("Johnny")
        .changeAge(26)
        .introduce()  // 출력: Hello, I'm Johnny and I'm 26 years old.
}

고차 함수

typealias IntOperation = (Int, Int) -> Int

fun highFunction(vararg x: Int, op: IntOperation): Int = x.toList().reduce(op) // 함수를 매개변수로 받음.
fun add(x: Int, y: Int): Int = x + y
fun returnFunction(): IntOperation = { x, y -> x + y } // 함수 반환

fun main() {
    println(highFunction(1, 2, 3, 4, op = { x: Int, y: Int -> x + y })) // 람다 전달
    println(highFunction(1, 2, 3, 4, 5, op = ::add)) // 함수 참조 전달
    println(returnFunction()(10, 20))
}

실행결과
10
15
30