함수형 프로그래밍이란
함수형 프로그래밍(FP)
순수 함수를 작성하여 프로그램의 부작용을 줄이는 기법
정의와 특징
- 순수 함수를 사용해야 한다.
- 람다식을 사용할 수 있다.
- 고차함수를 사용할 수 있다.
순수 함수
같은 인자에 대하여 항상 같은 값을 반환한다 (부작용이 없는 함수)
함수 외부의 어떤 상태도 바꾸지 않는다
람다식
수학에서 람다 대수는 이름이 없는 함수로 2 개 이상의 입력을 1개의 출력으로 단순화한다는 개념
FP에서는 다음을 의미
- 다른 함수의 인자로 넘기는 함수
- 함수의 결괏값을 반환하는 함수
- 변수에 저장하는 함수
일급 객체에 이름이 없는 경우, 이를 '람다식' 함수 또는 '람다식'이라 부름
일급 객체
FP에서는 함수를 일급 객체로 생각한다
일급 객체의 특징
- 일급 객체는 함수의 인자로 전달할 수 있다
- 일급 객체는 함수의 반환값에 사용할 수 있다
- 일급 객체는 변수에 담을 수 있다
고차 함수
다른 함수를 인자로 사용하거나 함수를 결과값으로 반환하는 함수를 의미
고차 함수와 람다식
고차 함수의 형태
인자에 일반 함수 사용, 반환값에 일반 함수 사용
fun main(){
val res2 = mul(sum(3,3), 3)
funFunc()
}
fun sum(a: Int, b: Int) = a + b
fun mul(a: Int, b: Int) = a * b
fun funcFunc(): Int{
return sum(2,2)
}
변수에 할당하는 람다식 함수
val multi = {x: Int, Int -> x * y} // 일반 변수에 람다식 할당
val result = multi(10, 20) // 람다식이 할당된 변수는 함수처럼 사용 가능
함수 내용에 표현식이 2줄 이상이라면 마지막 표현식이 반환값이 됨
val multi2: (Int, Int) -> Int = {x: Int, y: Int ->
println("x * y")
x * y // 마지막 표현식 반환
}
람다식 선언 자료형, 매개변수 생략
val multi: (Int, Int) -> Int = {x: Int, y: Int, x*y} // 생략되지 않은 전체 표현ㅍ
val multi = {x: Int, y: Int -> x * y} // 선언 자료형 생략
val multi: (Int, Int) -> Int = {x, y -> x * y} // 람다식 매개변수 자료형의 생략
val multi = {x, x -> x * y} // 오류 : 추론 불가능함
반환 자료형이 없는 경우, 매개변수가 하나인 경우, 람다식 안에 람다식인 경우
val greet: () -> Unit = {println("Hello World!")}
val greet = {println("Hello World!") // 자료형 생략 가능
val square: (Int) -> Int = {x -> x * x}
val square = {x: Int -> x * x} // x의 자료형을 명시해야 추론 가능
val nestedLambda: () -> () -> Unit = {{println("nested")}}
val nestedLambda = {{println("nested")}} // 자료형 생략 가능
람다식과 고차 함수 호출하기
이름에 의한 람다식 호출
fun main() {
val result = callByName(otherLambda) // 람다식 이름으로 호출
println(result)
}
fun callByName(b: () -> Boolean): Boolean { // 람다식 함수 자료형으로 선언된 매개변수
println("callByName function")
return b()
}
val otherLambda: () -> Boolean = {
println("otherLambda function")
true
}
람다식 자체가 매개변수 b에 복사되고, 사용되기 전까지는 람다식이 실행되지 않음.
callByName 함수에서 b를 실행할 때 비로소 람다식이 실행됨.
이름에 의한 호출 방법을 통해 필요할 때만 람다식이 작동하도록 만들 수 있다.
참조에 의한 호출 방식으로 일반 함수 호출하기 - 콜론 두 개(::)로 일반 함수를 람다식처럼 사용할 수 있다.
fun main() {
// 1. 인자와 반환 값이 있는 함수
// val res1 = funcParam(3, 2, sum) 오류 : sum은 람다식이 아님
val res1 = funcParam(3, 2, ::sum)
// 2. 인자가 없는 함수
hello(::text) // 반환값이 없음
hello({ a, b -> text(a, b) }) // 위의 식과 동일한 표현
hello { a, b -> text(a, b) } // 위의 식과 동일한 표현, 소괄호 생략 가능
// 3. 일반 변수에 값처럼 할당
val likeLambda = ::sum
}
fun sum(a: Int, b: Int) = a + b
fun text(a: String, b: String) = "Hi! $a $b"
fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int {
return c(a, b)
}
fun hello(body: (String, String) -> String): Unit {
println(body("Hello", "World"))
}
람다식의 매개변수
매개변수가 1개 있는 람다식 - it으로 매개변수를 대체 가능
onParam({a -> "Hello World! $a"})
onParam {"Hello World! $it"} // 화살표 표기를 생략하고 it으로 대체할 수 있음, 소괄호 생략 가능
2 개 이상의 람다식을 사용하는 경우
twoLambda({a, b -> "First $a $b"}, {"Second $it"})
twoLambda({a, b -> "First $a $b"}) {"Second $it"} // 소괄호 분리 가능
일반 매개변수와 람다식 매개변수 같이 사용하기
withArgs("Arg1", "Arg2", {a, b -> "Hello World! $a $b})
// 함수 인자의 마지막이 람다식인 경우 소괄호 분리 가능
withArgs("Arg1", "Arg2") {a, b -> "Hello World! $a $b}
reference : Doit! 코틀린 프로그래밍
'개발 > Kotlin' 카테고리의 다른 글
[코틀린] 코틀린 함수 (0) | 2021.12.10 |
---|---|
[코틀린] 변수와 자료형, Null 처리 (0) | 2021.12.08 |
코틀린(Kotlin) 스터디 4 - 클래스(Class), 상속(Inheritance) (0) | 2020.01.19 |
코틀린(Kotlin) 스터디 3 - Nullable, 예외처리, 함수 (0) | 2020.01.13 |
코틀린(Kotlin) 스터디 2 - Array, Collection(List, Set, Map) (0) | 2020.01.12 |
댓글