๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ][Kotlin] ๊ณ ์ฐจํ•จ์ˆ˜ HOF High-order Function, Combinator Pattern

์ถœ์ฒ˜

https://softwarepatternslexicon.com/patterns-kotlin/functional/combinator/

 

Combinator in Kotlin

Explore the Combinator Design Pattern in Kotlin, a powerful functional programming technique to combine functions, promoting flexible and reusable code. Learn how to implement and use combinators with real-world examples and programmatic illustrations.

softwarepatternslexicon.com

https://kotlinlang.org/docs/lambdas.html

 

Higher-order functions and lambdas | Kotlin

 

kotlinlang.org

ChatGPT

https://ko.wikipedia.org/wiki/%EA%B3%A0%EC%B0%A8_%ED%95%A8%EC%88%98

 

๊ณ ์ฐจ ํ•จ์ˆ˜ - ์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „

์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „. ๊ณ ์ฐจ ํ•จ์ˆ˜(้ซ˜ๆฌกๅ‡ฝๆ•ธ, higher-order function)๋Š” ์ˆ˜ํ•™๊ณผ ์ปดํ“จํ„ฐ ๊ณผํ•™์—์„œ ์ ์–ด๋„ ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.[1][2][3] ํ•˜๋‚˜ ์ด์ƒ์˜ ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ์ทจํ•œ๋‹ค. (์˜ˆ: ์ ˆ

ko.wikipedia.org

https://www.linkedin.com/pulse/higher-order-function-amit-nadiger

 

Higher-order function

In programming, functions are considered to be first-class citizens if they can be treated as any other value, such as an integer or a string. Higher-order functions (HOFs) are functions that take one or more functions as arguments and/or return a function

www.linkedin.com

https://medium.com/softaai-blogs/kotlin-higher-order-functions-d70a05eff805

 

Kotlin Higher-Order Functions

Kotlin is a modern programming language that is designed to be both functional and object-oriented. One of the features that makes Kotlin…

medium.com

 

 


๊ณ ์ฐจํ•จ์ˆ˜ High-order Function HOF

ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ฑฐ๋‚˜, ํ•จ์ˆ˜๋ฅผ ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜.

 

๊ณ ์ฐจํ•จ์ˆ˜์˜ ์žฅ์ 

1. ์žฌ์‚ฌ์šฉ์„ฑ

๊ณ ์ฐจํ•จ์ˆ˜๋Š” ๋‹ค์–‘ํ•˜๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ์ถ”์ƒํ™”์‹œ์ผœ ์žฌ์‚ฌ์šฉ์„ฑ์„ ์ด‰์ง„ํ•œ๋‹ค.

2. ์œ ์—ฐ์„ฑ

ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์–ด์„œ ์ฝ”๋“œ ์„ค๊ณ„์—  ๋†’์€ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค. 

3. ํ•จ์ˆ˜ ํ•ฉ์„ฑ

ํ•จ์ˆ˜๋“ค์„ ์กฐํ•ฉํ•ด ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ํ•จ์ˆ˜๋“ค์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ , ๋ณต์žกํ•œ ์—ฐ์‚ฐ์„ ์‰ฝ๊ฒŒ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

4 ํ–ฅ์ƒ๋œ ์ถ”์ƒํ™”

๋ณต์žกํ•œ ๋กœ์ง์„ ์ž‘์€ ํ•จ์ˆ˜๋กœ ๋‚˜๋ˆ  ์ถ”์ƒํ™”ํ•˜๊ณ , ๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋“ค์„ ๊ฒฐํ•ฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ๋ชจ๋“ˆํ™”์™€ ๊ตฌ์„ฑ ์š”์†Œ(ํ•จ์ˆ˜๋‚˜ ๋ชจ๋“ˆ)๋“ค์˜ ๊ฒฐํ•ฉ์ด ์šฉ์ดํ•ด์ง„๋‹ค.

 

๊ณ ์ฐจํ•จ์ˆ˜์˜ ๋‹จ์ 

1. ์„ฑ๋Šฅ

ํ•จ์ˆ˜ ์•ˆ์—์„œ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉฐ ์ƒ๊ธฐ๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ์˜ค๋ฒ„ํ—ค๋“œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋Œ€๋ถ€๋ถ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€์ด๋‹ค.

2. ๋ณต์žก์„ฑ ์ฆ๊ฐ€

์ฝ”๋“œ๋ฅผ ๋” ๋ณต์žกํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐœ๋…์ด ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ๋”์šฑ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

3. ๋””๋ฒ„๊น…์ด ์–ด๋ ต๋‹ค.

๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋””๋ฒ„๊น…ํ•˜๋Š” ๊ฒƒ์€ ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ๋ณต์žกํ•œ ์ œ์–ด ํ๋ฆ„์œผ๋กœ ์ธํ•ด ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ๋‹ค.

 

Combinator Pattern

๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜๋“ค์„ ๊ฒฐํ•ฉํ•ด ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์„ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋””์ž์ธ ํŒจํ„ด.

Combinator 

์ธ์ž๋กœ ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•„์„œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜.

Combinator Pattern์˜ ์žฅ์ 

1. ์žฌ์‚ฌ์šฉ์„ฑ

ํ•จ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์กฐํ•ฉํ•ด ๋‹ค์–‘ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

2. ์œ ์—ฐ์„ฑ

์ฝ”๋“œ์˜ ๋™์ž‘์„ ํ•จ์ˆ˜ ๊ฒฐํ•ฉ์œผ๋กœ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์‹œ

1. ์ฝ”ํ‹€๋ฆฐ์—์„œ ์ œ๊ณตํ•˜๋Š” fold ํ•จ์ˆ˜

fun <T, R> Collection<T>.fold(
    initial: R,
    combine: (acc: R, nextElement: T) -> R
): R {
    var accumulator: R = initial
    for (element: T in this) {
        accumulator = combine(accumulator, element)
    }
    return accumulator
}

 

fold ํ•จ์ˆ˜์—์„œ, combine ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜ ํƒ€์ž… (R, T) -> R์„ ๊ฐ€์ง€๊ณ , R ๋ฐ T ํƒ€์ž…์˜ ๋‘ ์ธ์ˆ˜๋ฅผ ๋ฐ›์•„ R ์œ ํ˜•์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์ด๋Š” Collection์˜ for ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœ๋˜๊ณ  ๋ฐ˜ํ™˜ ๊ฐ’์€ accumulator์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

 

2. ๋‹ค๋ฅธ ์˜ˆ์ œ

fun <T, R, V> ((T) -> R).andThen(next: (R) -> V): (T) -> V = {
    next(this(it))
}

val multiplyBy2: (Int) -> Int = { it * 2 }
val add10: (Int) -> Int = { it + 10 }

val combinedFunction = multiplyBy2.andThen(add10)
println(combinedFunction(5))  // ์ถœ๋ ฅ: 20 (5 * 2 + 10)

 

andThen ํ•จ์ˆ˜๋Š” ๋‘ ํ•จ์ˆ˜๋ฅผ ์กฐํ•ฉํ•ด ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. multiplyBy2 ํ•จ์ˆ˜์™€ add10 ํ•จ์ˆ˜๋ฅผ ๊ฒฐํ•ฉํ•ด, ์ˆซ์ž๋ฅผ 2๋ฐฐ๋กœ ๊ณฑํ•œ ํ›„ 10์„ ๋”ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์กŒ๋‹ค.