-
[Swift] ํจ์ํ ํ๋ก๊ทธ๋๋ฐ (Functional Programming)Swift 2022. 1. 21. 23:19
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ ์ฐจ์งํฅ ํ๋ก๊ทธ๋๋ฐ๊ณผ ์๋ฐ๋๋ ๊ฒ์ด ์๋๋ผ ์ ์ฐจ์งํฅ์ ์์๋ค๊ณผ ๊ณต์กดํ๊ธฐ๋ ํ๊ณ , ์ด๋ค์ ํฌํจํ๊ธฐ๋ ํ๋ ๊ฐ๋ ์ด๋ค.
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ๋ ๊ฐ์ฒด์งํฅ๊ณผ ๋๋ฆฝํ๋ ๊ด๊ณ๋ ์๋๋ค. ํ๋ก๊ทธ๋๋จธ๋ค์ด ์ผํ๋ ์๋ก์ด ํจ๋ฌ๋ค์์ ์ ์ํ ๊ฒ.
ใ ค
ใ คํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์์๋ฅผ ์ด์ฝ๋ ๊ณต์ฅ์ผ๋ก ๋ํ๋ด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
๋น ํจ์ํ
๊ณต์ฅ ํ๋ก์ธ์ค๋ฅผ ๊ฐ ๊ตฌ์ฑ์์ด ์๊ณ ์๋ค. ๋ค๋ฅธ ๊ณณ์ ๋ฌด์ธ๊ฐ๋ฅผ ์ ์ด๋๊ณ ์ฐธ์กฐํ๊ธฐ๋ ํจ. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ ํจ์๋ค์ด ์ฌ์ฉํ๋ ์ธ๋ถ ๋ณ์์ ์ค๋ฅ๊ฐ ์๊ธฐ๋ฉด, ๊ณต์ฅ ํ๋ก์ธ์ค์ ์ฐจ์ง์ด ์๊ธธ ์ ๋ฐ์ ์๋ค.
๊ฐ ๊ตฌ์ฑ์๋ค์ด ๋งก์ ์ญํ ์ ๋ฐ๋ผ ํ๋ ฅํ๋ฉฐ ์ผํจ. ์์คํ ์ ๊ตฌ์ถํ๊ธฐ ์ํ ์ค๊ณ์์ ๊ณ ๋ฏผ์ด ํ์.

ใ ค
ใ ค
ํจ์ํ
๊ฐ ๊ตฌ์ฑ์๋ค์ ๊ณต์ฅ ํ๋ก์ธ์ค์ ๋ํด ์์ง ๋ชปํจ.
์ธํ๊ณผ ์์ํ์ด ์๋ค. ๊ฐ ๊ตฌ์ฑ์๋ค์๊ฒ ์ผ์ ์ํค๋ ๋ฐฉ๋ฒ์, ๊ทธ๋ค์ ์ญํ ๋๋ก ์ฒ๋ฆฌํ ์ค๊ฐ์ฌ๋ฃ๋ฅผ ๋๊ฒจ์ฃผ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฉด ๊ฐ์ ๋งก์ ์์ ์ ํด์ ๊ฒฐ๊ณผ๋ฌผ์ ๋ฐํํ๊ฒ ๋๋ค.
์ธ๋ถ ํ๊ฒฝ์ผ๋ก๋ถํฐ ์ฒ ์ ํ ๋ ๋ฆฝ์ ์. ๋น ํจ์ํ ๊ณต์ฅ์ฒ๋ผ ๋ค๋ฅธ ๊ณณ์ ๋ฌด์ธ๊ฐ๋ฅผ ์ ์ด๋์ง๋, ์ฐธ์กฐํ์ง๋ ์๋๋ค. ์ค๋ก์ง ์์ ๋ค์๊ฒ ์ฃผ์ด์ง๋ ๊ฒ๋ค๋ก๋ง ์ ํด์ง ์์ ์ ํ๋ค.
๊ฐ์ ์ธํ์ ์์ด์ ์ธ์ ๋ ๋์ผํ ์์ํ์ ์์ฐํ๋ค. ์ด๋ ์ธ๋ถ ํ๊ฒฝ์ผ๋ก๋ถํฐ ์ฒ ์ ํ ๋ ๋ฆฝ์ ์ด๊ธฐ ๋๋ฌธ. ์ธ๋ถ ์์ธ์ ์ํฅ์ ๋ฐ์ง ์์ผ๋ฏ๋ก ์ฒ ์ ํ ๋ค์ด์ค๋ ์ฌ๋ฃ์ ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๋ฌผ์ด ๋ง๋ค์ด์ง๊ณ , ๋ค๋ฅธ ๊ตฌ์ฑ์๋ค์ ๋ํด์๋ ๋๊ฒจ์ฃผ๋ ๊ฒฐ๊ณผ๋ฌผ ์ธ์๋ ์๋ฌด ์ํฅ์ ์ฃผ์ง ์๋๋ค. ์ด๋ฐ ๊ฒ์ ์์ ํจ์๋ผ๊ณ ํ๋ค.
๋ถ์์ฉ์ ์ํ ๋ฌธ์ ๋ก๋ถํฐ ๋ณด๋ค ์์ ๋กญ๋ค. ๋ถ์์ฉ์ด๋, ์ด๋ค ํจ์์ ๋์์ ์ํด ํ๋ก๊ทธ๋จ ๋ด ํน์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ ์ํฉ์ ๋งํ๋ค. ๋ณ๊ฒฝ๋ ์ํ๋ ๊ด๋ จ๋ ๋ค๋ฅธ ๋์๋ค์๊ฒ ์ํฅ์ ๋ฏธ์น๋ค.

ใ ค
ใ ค
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ
- ํจ์์ ๋์์ ์ํ ๋ณ์์ ๋ถ์์ ์ธ ๊ฐ ๋ณ๊ฒฝ์ ์์ฒ ๋ฐฐ์ ํจ์ผ๋ก์จ ๋ถ์์ฉ์ ์ํ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๋ ๊ฒ. ์ฆ, ๋ฌธ์ ์ ์์ง๊ฐ ์๋ ์ผ์ ํ์ง ์๋ ์ฝ๋ฉ ๋ฐฉ์.
- ์ธ๋ถ ๋ณ์๋ฅผ ์ฌ์ฉํ๋๋ผ๋, ๊ทธ ๋ณธ์ฒด์ ์ ๊ทผํด์ ๋ณ๊ฒฝํ๋ ๊ฒ ์๋๋ผ ์ธ์๋ก ๋ฃ์ด์ ์ฌ๋ณธ์ผ๋ก ๋ณต์ฌํด๊ฐ์ ์์ ์ ํ๊ธฐ ๋๋ฌธ์ ์ด๋ค ์์ ์ ํ๋ ๋ถ์์ฉ์ ์ผ์ด๋์ง ์๋๋ค.
- ์๋ฌด ๋ณ์ ๊ฐ๋ ๋ฐ๊พธ์ง ์์ผ๋ฉด์, ๊ณ ์ ๊ฐ๋ง ์ฐ๋ฉด์ ์ํํธ์จ์ด๋ฅผ ๋ง๋ ๋ค๋ ๊ฒ์ ์๋ฌด๋ฐ ์ํ๋ณํ๋ฅผ ์ผ์ผํค์ง ์๋๋ค๋ ๋ง์ ์๋๋ค. ๋ชจ๋ ๊ฒ์ 100% ํจ์ํ ๊ธฐ์ค์ ๋ง์ถ๋ ๊ฒ์ ์ด๋ ต์ง๋ง, ์ ์ด๋ ์ผ์ ๋จ์์ ์์ ์ ์์ด์๋ ๋ถ์ํจ๊ณผ ์์ด ์์ ์ ์ด๊ณ ์์ธก ๊ฐ๋ฅํ ํ๋ก๊ทธ๋จ์ ์ง๋ ๊ฒ์ด ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ด๋ค.
- ๋ฉํฐ ํ๋ก์ธ์ฑ์ด ์ค์ํด์ง ์ค๋๋ ๋์ฑ ๋ ์ฃผ๋ชฉ๋ฐ๊ณ ์๋ค.
ใ ค
ใ ค
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๋ํ์ ํน์ง๊ณผ ์์
1. ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ ์ธํ์ด๋ค.
๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์ โ๋๋ ์ด๊ฑธ ํ๊ณ ๋๋ ์ ๊ฑธ ๋๊ตฌ๋ ์ด๋ป๊ฒ ํด์ ์ด๋ฌ์ด๋ฌํ ๊ฒฐ๊ณผ๋ฅผ ์ฐ์ถํด๋ด๋ผโ ํ๋๊ฒ ๋ช ๋ นํ์ผ๋ก ์ฌ๊ณ ํ๋ ๊ฒ


ํจ์ํ ํ๋ก๊ทธ๋๋ฐ โ ์ด๊ฑฐโ๋โ ์ด๊ฑฐ๋ค.
ํจ์ํ ๋ฐฉ์์ผ๋ก ์ง์ธ ์์ ํจ์๋ค์ ์ธํ๋ง ๋๊ฐ์ผ๋ฉด ์ ๋ ๋ค๋ฅธ ์์ธ์ ์ํ ๋ณ์๊ฐ ์๊ธฐ ๋๋ฌธ์, ์ด๊ฑฐโ๋โ ์ด๊ฑฐ๋ค. ์นด์นด์ค๋ฅผ ๋ฃ์ ๊ฒฐ๊ณผ๋ ๋ฌด์กฐ๊ฑด ์ด์ฝ๋ ์ด๋ค. ๋ผ๋ ๊ฑธ ์ฅ๋ดํ ์ ์๋ค.
ํจ์๋ ๋ณ์์ฒ๋ผ ์๊ฐํ๋ฉด ๋๋ค. ํจ์๋ฅผ ๊ฐ์ผ๋ก ๋ณด๊ณ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ ๊ฒ.

ใ ค
2. ํจ์๋ โ๊ฐโ์ด๋ค.
ํจ์๋ ๊ฐ ํํ๋ก๋ ์ ์ธ๋ ์ ์๋ค.
var sum: (Set<Int>) -> Int = { $0.reduce(0,+) }๋ณ์์ ๋ด๊ธด ํจ์๋ค์ ํธ์ถํ ์๋ ์๊ณ , ๋ค๋ฅธ ํจ์ ๋ฑ์ ์ฝ๋ฐฑ์ผ๋ก ๋ฃ์ด์ค ์๋ ์๋ค.
var sum: (Set<Int>) -> Int = { $0.reduce(0,+) } print(sum([1, 2, 3])) func myFunc(closure: (Set<Int>) -> Int) { print(closure([1, 2, 3, 4, 5])) } myFunc(closure: sum)ํจ์ ์์ฒด๋ก๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์๋๋ค. ์ธ์๋ก ๋ฌด์ธ๊ฐ๊ฐ ๋ค์ด๊ฐ์ผ ๊ฒฐ๊ณผ๊ฐ์ด ๋์จ๋ค.
ํจ์๊ฐ ์์ํจ์์ผ ๊ฒฝ์ฐ, ์ธํ์ผ๋ก ํ๋ ์ผ์ ์ผ์ ํ๊ธฐ ๋๋ฌธ์ ์ธ์๋ก ๊ฐ์ ๋ฃ์ผ๋ฉด ์ธ์๋ก์จ ์ ๋ ์์ธก๊ฐ๋ฅํ ๊ฐ์ ์์ํ์ผ๋ก ๋ด๊ฒ ๋๋ ์ํ๋ผ๋ ๊ฐ์ผ๋ก ํจ์๋ฅผ ๋ฐ๋ผ๋ณผ ์ ์๊ฒ ๋๋ค.
ใ ค
3. ๊ณ ๊ณํจ์
์ธํ์ด ์๋ ํจ์๋ ํน์ ๊ฐ์ ์ธ์๋ก ๋ฐ๋๋ค.
ํจ์๋ฅผ ๊ฐ์ผ๋ก ๋ณผ ์ ์๋ค๋ฉด, ํจ์๋ ๋ค๋ฅธ ํจ์์ ์ธ์๋ก ๋ฃ์ด์ค ์ ์๋ค.
์ธ์๋ก ๋ค๋ฅธ ํจ์๋ฅผ ๋ฐ์ ๊ฒฐ๊ณผ๊ฐ์ ๋ด๋ณด๋ด๋ ํจ์๋ฅผ ๊ณ ๊ณํจ์๋ผ๊ณ ํ๋ค.
๊ฐ์ ์ธ์๋ก ์ฃผ์ด์ง ๋ฟ๋ง ์๋๋ผ, ๊ฒฐ๊ณผ๊ฐ์ผ๋ก ๋ฐํ๋๊ธฐ๋ ํ๋ค. ๋ค๋ฅธ ํจ์๋ฅผ ๋ฐํํ๋ ํจ์๋ ๊ณ ๊ณํจ์์ ์ํ๋ค.
์๋ ์ฝ๋๋ ๋ค์ด์จ ์ธ์ ๊ฐ์ผ๋ก ์ด๋ค ์ฐ์ฐ์ ํ ์ง ํ๋จํ๊ณ , ๊ทธ์ ๋ง๋ ํจ์๋ฅผ ๋ฆฌํดํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
func add(a: Int, b: Int) -> Int { return a + b } func sub(a: Int, b: Int) -> Int { return a - b } func mul(a: Int, b: Int) -> Int { return a * b } func div(a: Int, b: Int) -> Int { return a / b } func calculate(op: String) -> ((Int, Int) -> Int)? { switch op { case "add": return add(a:b:) case "sub": return sub(a:b:) case "mul": return mul(a:b:) case "div": return div(a:b:) default: return nil } } print(calculate(op: "add")?(2, 5)) // Optional(7) print(calculate(op: "mul")?(2, 5)) // Optional(10)
์๋ ์ฝ๋ ์ค๋ช
calculate2 ํจ์์ add๋ฅผ ์ธ์๋ก ๋ฃ์ ๊ฒฐ๊ณผ๋ฅผ add2์ ๊ฐ์ผ๋ก ์ ์ฅํ๊ณ , add2๋ ํจ์๋ฅผ ๋ฐํํ๋ ํจ์์ด๋ฏ๋ก add2์ ๊ฐ์ผ๋ก๋ ํจ์๊ฐ ๋ค์ด๊ฐ์๋ ๊ฒ์ด๋ค.
add2์ ์ธ์๋ก (3, 5)๋ฅผ ์ ๋ฌํ๋ฉด 3๊ณผ 5๊ฐ ๋ํด์ ธ์ 8์ด ์ถ๋ ฅ๋๋ค.
์ฆ, add2๋ calculate2 ํจ์์ add ํจ์๋ฅผ ์ธ์๋ก ๋ฃ์ผ๋ฉด, add ํจ์์ ์ธ์๋ก ์ ๋ฌ๋ ์ซ์ 2๊ฐ๊ฐ ๋ํด์ ธ์ ๋์ค๋ ํจ์๊ฐ ๋ง๋ค์ด์ง ๊ฒ์ด๋ค.
calculate2์ mul์ ์ธ์๋ก ์ ๋ฌํด์ ๋ง๋ mul2 ํจ์๋ mul2์ 2์ 5๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ฉด 10์ด ์ถ๋ ฅ๋๋ค.
func calculate2(_ op: @escaping (Int, Int) -> Int) -> (Int, Int) -> Int { return { op($0, $1) } } let add2 = calculate2(add) print(add2(3, 5)) // 8 let mul2 = calculate2(mul) print(mul2(2, 5))
ํ๋ก๊ทธ๋จ์ด ๋์ํ๋ ์ค์ ํจ์๊ฐ ๋ง๋ค์ด์ง๋ค!
ใ ค
4. ์ปค๋ง
add_curry(2)๊ฐ ๋จผ์ ์คํ๋ ํ, ๊ทธ ๊ฒฐ๊ณผ
์ฌ๋ฌ ์ธ์๋ฅผ ๋ฐ๋ ํจ์์ ์ผ๋ถ ์ธ์๋ง ๋ฃ์ด์ ๋๋จธ์ง ์ธ์๋ฅผ ๋ฐ๋ ๋ค๋ฅธ ํจ์๋ฅผ ๋ง๋ค์ด๋ผ ์ ์๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ.
๋ชจ๋ ์ธ์๋ค์ด ์ค๋น๋์ง ์์์๋, ๋ถ๋ถ์ ์ฉ๋ ์ํ์ ํจ์๋ฅผ ๋ง๋ค์ด๋ด์ ๋ง๋ จํด๋๊ฑฐ๋ ๋ค๋ฅธ ํจ์์ ์ธ์๋ก ๋๊ฒจ์ฃผ๋ ๋ฑ, ๋ก์ง์ ์ง๋ ๋ฐฉ์์ด ๋ ํ์ฑํด์ง๊ณ ์ฝ๋๋ ์ค์ผ ์ ์๋ค.


ใ ค
5. ํจ์ ์ปด๋น๋ค์ดํฐ
๋ฐฐ์ด์ด๋ ๋ฆฌ์คํธ ๊ฐ์ ์ปฌ๋ ์ ์์ ์์ฃผ ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ์ด๋ค.
ํจ์ํ ์ธ์ด๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์๋ ์ด๋ ๊ฒ ์ปฌ๋ ์ ๋ด์ ์์๋ค์ ๋ค์ํ๊ฒ, ์ฐ์์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ๋ง์ ๋๊ตฌ๋ค์ด ํ์ฌ๋์ด์๋ค.
์ฐ๋ฆฌ๊ฐ ์ด์ ์๋ ์ง์ for ๋ฌธ์ ๋๋ฆฌ๊ณ , ๋ณ์ ์ง์ ํด๊ฐ๋ฉฐ ํ๋ํ๋ ์ค๊ณํ๊ณ ์์ ํด์ผํ๋, ์ค์์ ์ฌ์ง๋ ์๊ณ ๋ถ์์ฉ๋ ๋ถ๊ฐํผํ ์์ ๋ค์ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์๋ ์ด๋ฐ ๋ค์ํ ๋๊ตฌ๋ค์ ์๋๊ณผ ์ฌ์ฉ๋ฒ์ ์ตํ๋์๋ค๊ฐ ์ด๋ป๊ฒ ํ์ฉํ ์ง ์๊ฐํด์ ์ฌ์ฉํ๋ฉด ๋๋ ๊ฒ.
ํจ์ํ ์ธ์ด๊ฐ ์๋๋๋ผ๋, ReactiveX์์ ์ ๊ณตํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํด์ ๊ฑฐ์ ๋ชจ๋ ์ธ๊ธฐ ์ธ์ด๋ค์์ ์ด๋ฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ค.



for๋ฌธ์ด๋ while๋ฌธ ๋ฑ ๋ฐ๋ณต๋ฌธ์ ์์๋ค์ ํน์ ๋ณ์์ ์ํ ๋ณํ, ์ฆ ๋ถ์ํจ๊ณผ๋ฅผ ํ์๋ก ํ๋ค. ๋๋ฌธ์ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์๋ ๋ถ์ํจ๊ณผ๋ฅผ ์ผ์ผํค์ง ์๋ ์ฌ๊ทํจ์๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ค.
ใ ค
์ถ์ฒ'Swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] init(_:radix:uppercase:) (0) 2022.02.02 [Swift] init(_:radix:) (0) 2022.02.02 [Swift] ๊ณ ์ฐจํจ์ (map, filter, reduce) (0) 2022.01.20 [Swift] ๋จ๋ฝ ํ๊ฐ (Short-circuit Evaluation), Side Effect (0) 2022.01.20 [Swift] zip(_:_:) (0) 2022.01.14