์ด๋ฒ ํฌ์คํธ๋ http://learnyouahaskell.com/higher-order-functions ์ ๊ทผ๊ฑฐํ๊ณ ์์ต๋๋ค.
๐ ๊ณ ์ฐจํจ์ (High Order Function)
๊ณ ์ฐจํจ์
๋ ํจ์๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ์ค ์ ์๊ณ , ๋ฐํ๊ฐ์ผ๋ก๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
ํ๋ง๋๋ก ํจ์๋ฅผ ๊ฐ์ผ๋ก ์ทจ๊ธํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๐ ์ปค๋ง (Currying)
Haskell ๋ค์ค์ธ์ ํจ์์ ์ ์ฒด
ํ์ค์ผ์ ํจ์๋ ํ๋์ ์ธ์๋ง ๋ฐ์ ์ ์๋๋ก ๋์ด์๋๋ฐ,
์ด๋ป๊ฒ ์ฌ๋ฌ๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋ ํจ์๋ฅผ ๊ตฌํํ ์ ์๋ ๊ฒ์ผ๊น์?
๋ ์ธ์๋ฅผ ๋ฐ์ ํฐ ๊ฐ์ ๋ฐํํ๋ ํจ์ max
๋ ๋ค์๊ณผ ๊ฐ์ด ๋ ๋จ๊ณ๋ก ๋๋ ๋ณผ ์ ์์ต๋๋ค.
ghci> max 4 20
20
{- โ
์ ํํ์์ ๋ค์๊ณผ ๊ฐ์ด ๋ถ๋ฆฌํ ์ ์๋ค. -}
ghci> maxValueWith4 = max 4
ghci> maxValueWith4 20
20
์์ ๊ฐ์ด Haskell
์์ ๋ค์ค ์ธ์ ํจ์๋ ์ฌ์ค ์ฌ๋ฌ๊ฐ์ ์ปค๋ง ํจ์๋ก ๊ตฌ์ฑ ๋ฉ๋๋ค.
์ปค๋ง๊ณผ ๋ถ๋ถ์ ์ฉ
์ปค๋ง(currying)
์ n ๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋ ํจ์๋ฅผ n๊ฐ์ ๋จํญ ํจ์๋ก ๋ณํํ๋ ๊ฒ์
๋๋ค.
n๊ฐ์ ๋จํญํจ์ ๊ฐ๊ฐ์ ๊ทธ ๋ค์ ์ฒด์ธ์ ํจ์๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ ๊ณ ์ฐจํจ์
๊ฐ ๋ฑ์ฅํฉ๋๋ค.
์ปค๋ง
์ ํ์ฉํ๋ฉด ๋ถ๋ถ์ ์ฉ
ํตํด์ n ๊ฐ์ ์ธ์๋ฅผ ๋ชจ๋ ์ ๊ณต๋ฐ์ ๋๊น์ง ์คํ์ ์ง์ฐ์ํฌ ์ ์์ต๋๋ค.
๋ถ๋ถ์ ์ฉ
์ ํ์ํ ์ธ์๋ค ์ค ์ผ๋ถ๋ง ์ ์ฉ๋ ํจ์์
๋๋ค.
๋ํ์ ์ผ๋ก Haskell
์ prefix function
์ ์์๋ก ๋ค ์ ์์ต๋๋ค.
ghci > :type (+3)
(+3) :: Num a => a -> a
{- ์ ํํ์์ 3์ ๋ํ๋ ํจ์๋ฅผ ๋ฐํํ๋ค. -}
์ปค๋ง๊ณผ ๋ถ๋ถ์ ์ฉ์ ์ฐจ์ด
์๋ฐํ ๋งํ์๋ฉด ๋ ๊ฐ๋ ์ ์ ์ฌํ์ง๋ง ๋์๋ฐฉ์์ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
์ปค๋ง
์ ์๊ฒฉํ ๋ถ๋ถ์ ์ฉ
์ ํ๊ฐ์ง ๋ฐฉ๋ฒ์ด๋ผ๊ณ ๋ณผ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
- ์ปค๋ง : ์ฒด์ธ์ ๋ค์ ํจ์๋ฅผ ๋ฐํํฉ๋๋ค.
- ๋ถ๋ถ์ ์ฉ : n๊ฐ์ ์ธ์๋ฅผ ๊ฐ์ง๋ ํจ์์์ n-m ๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋ ํ๋์ ํจ์๋ฅผ ๋ฐํํฉ๋๋ค.
์ธ์๊ฐ ๋๊ฐ๋ผ๋ฉด ๋์ผํ๊ฒ ๋์ํ๊ฒ ์ง๋ง, ๊ทธ ์ด์์ ์ธ์๋ฅผ ๊ฐ์ง๋ ํจ์๋ผ๋ฉด ๋์ ๋ฐฉ์์ด ๋ฌ๋ผ์ง๋๋ค.
์๋ฅผ ๋ค์ด func ์ด x, y, z ๋ผ๋ ์ธ์๋ฅผ ๋ฐ๋๋ค๋ฉด,
์ปค๋ง์ 3๊ฐ์ ๋จํญ ํจ์๋ฅผ ๋ฐํํ์ฌ ๊ฒฐ๊ณผ์ ์ผ๋ก func(x)(y)(z) ์ ์ฒด์ธ ๊ตฌ์กฐ๋ก ํธ์ถ๋๊ณ
๋ถ๋ถ์ ์ฉ์ x ๋ฅผ ์ธ์์์ ์ ์ธํ ๊ฒฝ์ฐ func(y, z) ๋ก ํธ์ถํฉ๋๋ค.
์ ๋ฆฌํ์๋ฉด, ๊ณ ์ฐจํจ์์ ์์๋?
ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์๋ ๊ณ ์ฐจํจ์๋ฅผ ์ด์ฉํด์ ๊ณตํต๋ ํจํด์ ์ถ์ํ
ํ ์ ์์ต๋๋ค.
์ด๋ฅผ ํตํด ์ฌ์ฌ์ฉ์ฑ
์ด ๋์์ง๋ฉฐ ๊ฐ๋
์ฑ
์ด ์ข์ ํจ์๋ฅผ ์ค๊ณํ ์ ์์ต๋๋ค.
๋ช ๋ นํ ํ๋ก๊ทธ๋๋ฐ์์๋ ๊ฐ์ ๋ฐฉ์์ ์ํด์ ๋ฐ๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ๋ณ์๋ฑ์ ํจ์๋ก ์ด๋ฅผ ๊ฐ์ธ ๊ตฌํํฉ๋๋ค.
๋ํ ๋ถ๋ถ์ ์ฉ
์ ํ์ฉํ๋ฉด ํธ์ถ์์ ์ ํด๋น ๊ฐ์ด ํ์ํ ์์ ๊น์ง ์ง์ฐ
์ํฌ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
๐ ๋๋ค ํจ์
๋๋ค ํจ์๋ ์ต๋ช
ํจ์์
๋๋ค. ๋ง ๊ทธ๋๋ก ์ด๋ฆ์ด ์๋ ํจ์
์
๋๋ค.
Haskell
์์๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
\x -> x + 1
์ ๋๋คํจ์๋ฅผ ์ฌ์ฉํ ๊น์?
๋๋คํจ์๋ ํน์ ์ด์ ๋ก ํ๋ฒ ์ฌ์ฉํ๊ณ ๋ง ํจ์์ ์ ์ฉํ๋ฉฐ
๋๋ฌธ์ ์ฃผ๋ก HOF ์ ์ธ์๋ก ํจ์๋ฅผ ๋๊ธธ๋ ๋๋คํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ง์ฝ ๋๋คํจ์๊ฐ ์๋ค๋ฉด, ๋ค์๊ณผ ๊ฐ์ด where
block ์ ์ด์ฉํ์ฌ ๊ตฌํํ ์ ์์ต๋๋ค.
ghci> addOneMap arr = map addOne arr where addOne x = x + 1
ghci> addOneMap [1,2,3]
[2,3,4]
๋๋คํจ์๋ฅผ ์ด์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํํํ ์ ์์ต๋๋ค.
addOneMap arr = map (\x -> x + 1) arr
๋๋คํจ์๋ฅผ ํตํด ํ์ ์ ์ธ ํํ์ ๋ ๊ฐ๊น๊ฒ ํจ์ ํํํ๊ธฐ
์ ์์ ์๊ฐ๋ ๋๋คํจ์๋ฅผ ์ด์ฉํ ํฅ๋ฏธ๋ก์ด ์์ ๊ฐ ์์ต๋๋ค.
์ธ ์ธ์๋ฅผ ๋ํ๋ ํจ์ addThree
๋ ๋ค์๊ณผ ๊ฐ์ด ํํํ ์ ์์ต๋๋ค.
addThree :: (Num a) => a -> a -> a -> a
addThree x y z = x + y + z
Haskell
์ ๋ชจ๋ ํจ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ปค๋งํจ์์ด๊ธฐ ๋๋ฌธ์ ์ ํํ์์ ๋ค์๊ณผ ๋์ผํฉ๋๋ค.
addThree :: (Num a) => a -> a -> a -> a
addThree = \x -> \y -> \z -> x + y + z
๋๋คํจ์๋ฅผ ์ด์ฉํ ํํ์์ด ํ์ ์ ์ธ๊ณผ ์ข ๋ ๊ฐ๊น์ด ํํ์ด์ง๋ง, ์ฝ๊ธฐ ์ฌ์ด ํํ๋ ์ฒซ๋ฒ์งธ ํํ์์ด๊ธฐ ๋๋ฌธ์
๋ณดํต ์ด๋ ๊ฒ๊น์ง ํํํ์ง๋ ์์ต๋๋ค.
๐ fold ์ scan ํจ์
fold
์ scan
๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์์ map
, filter
์ ํจ๊ป ๊ฐ์ฅ ์์ฃผ ํ์ฉ๋๋ ํจ์์
๋๋ค.
๋ ํจ์ ๋ชจ๋ ์ํ๋ฅผ ํ๋ ๋ฐฉํฅ์ ๋ฐ๋ผ left side
์ right side
๋ก ๊ตฌ๋ถ๋ฉ๋๋ค.
์ด ๋ ํจ์ ๋ชจ๋ ๋ค์ ์ธ๊ฐ์ง ์์๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
binary function
starting value
fold
ํ ๋์list
์ํ์์ binary function(์ด์ง ํจ์)
๋ ๋ ๊ฐ์ ์
๋ ฅ์ ๋ฐ๋ ํจ์๋ฅผ ์๋ฏธํฉ๋๋ค.
๋ณด๋ค ์ ํํ ํด์ํ์๋ฉด ์๋ก ๋ค๋ฅธ ๋ ์งํฉ X, Y ์ ๋ฐ์นด๋ฅดํธ ๊ณฑ์ ๊ฒฐ๊ณผ์ธ Z ๋ฅผ ๋ง์กฑ์ํค๋ ํจ์์ ๋๋ค.
๋จผ์ fold
ํจ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
foldl, foldr ์ดํด๋ณด๊ธฐ
fold
ํจ์๋ ๋ฆฌ์คํธ ์ํ ๋ฐฉํฅ์ ๋ฐ๋ผ foldl, foldr
๋ก ๊ตฌ๋ถ๋ฉ๋๋ค.
์ฌ๊ธฐ์ foldl
์ ->
๋ฐฉํฅ, foldr
์ <-
๋ฐฉํฅ์
๋๋ค.
์ด ํจ์๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ธฐ ์ํ ๊ฐ๋จํ ์์๋ก maximum
ํจ์๋ฅผ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
ํด๋น ํจ์๋ ์ธ์๋ก ์ฃผ์ด์ง ๋ฆฌ์คํธ์ ์์ ์ค ๊ฐ์ฅ ํฐ ๊ฐ์ ๋ฐํํฉ๋๋ค.
ghci> maximum' (x:xs) = foldr (\x acc -> max x acc) x xs
ghci> maximum' [2, 10, 11, 4]
11
์์ ์ค๋ช
ํ ๋๋ค ํจ์๋ฅผ foldr
์ binary function
์ผ๋ก ๋๊ฒจ์ฃผ๊ณ
starting value
๋ ํจํด ๋งค์นญ์ ํตํด ๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ์์๋ก ์ง์ ํฉ๋๋ค.
์ฌ๊ธฐ์ foldr1
๋ฅผ ์ด์ฉํ๋ฉด ํจ์๋ฅผ ๋ ๊ฐ๋จํ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
์ด ํจ์๋ starting value
๋ฅผ ๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ์์์์ ๊ฐ์ ธ์ต๋๋ค.
์ด๋ฅผ ํตํด ํจํด๋งค์นญ์ ์ ๊ฑฐํ ์ ์์ต๋๋ค.
ghci> maximum' arr = foldr1 (\x acc -> max x acc) arr
์์ ์ดํด๋ณด์๋ฏ์ด max
๋ํ ์ปค๋ง ํจ์์ด๊ธฐ ๋๋ฌธ์ ๋๋คํจ์๋ฅผ ์์ ๊ณ ๋ค์๊ณผ ๊ฐ์ด ๋ํ๋ผ ์ ์์ต๋๋ค.
ghci> maximum' arr = foldr1 max arr
์ฌ๊ธฐ์ eta conversion
์ ์ฌ์ฉํ๋ฉด ํจ์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๊ฑฐํ ์ ์์ต๋๋ค.
์ด๋ฅผ ํตํด point free style
ํจ์๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค.
ghci> maximum' = foldr1 max
๐ก (์ฐธ๊ณ ) eta conversion
๋๋ค ๋์(lambda calculus) ์ rewrite rules ์ค ํ๋์ ๋๋ค.
1. \x -> abs x
{- 1. ์์ 2. ๋ก ๋ณํํ๋ ๊ฒ์ eta reduction, ๊ทธ ๋ฐ๋๋ฅผ eta expansion ์ด๋ผ๊ณ ํฉ๋๋ค. -}
2. abs
What does eta reduce mean in the context of HLint
๊ทธ์ธ์ foldl, foldr ๋ฅผ ์ด์ฉํ ๋ค์ํ ์์
map
๊ณผ filter
๋ fold
ํจ์๋ก ๊ตฌํ ๊ฐ๋ฅํฉ๋๋ค.
ghci> map' f = foldr (\x acc -> f x : acc) []
ghci> map' (*3) [1, 2, 3]
[3,6,9]
ghci> filter' p = foldr (\x acc -> if p x then x : acc else acc) []
ghci> filter' (>10) [11, 9, 2, 130, -1]
[11,130]
ghci> reverse' = foldr (\x acc -> acc ++ [x]) []
ghci> reverse' [1, 2, 3]
[3,2,1]
ghci> reverse' = foldl (\acc x -> x : acc) []
ghci> reverse' [1, 2, 3]
[3,2,1]
์ฌ๊ธฐ์ foldl
์ ํ์ฉํ reverse
์์๋ ๋ค์๊ณผ ๊ฐ์ด ์ถ์ฝํ ์๋ ์์ต๋๋ค.
์ผ์ชฝ์์๋ถํฐ ์ํํ๊ธฐ ๋๋ฌธ์ binary function
์ ๋ ์ธ์ acc
์ x
๋ฅผ ๋ถ์ธ ๋ค์,
์ด๋ฅผ ๋ค์ง์ผ๋ฉด(flip) ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
ghci> reverse' = foldl (flip (:)) []
foldl vs foldr
foldl
๊ณผ foldr
์ infinite list
๋ฅผ ๋ค๋ฃจ๋ ๊ด์ ์์ ์ฐจ์ด๊ฐ ์กด์ฌํฉ๋๋ค.
[x1, x2, x3, ...]
์ ๋ฆฌ์คํธ์ ํจ์ f
๋ฅผ ์ ์ฉํ๊ณ ์ด๊ธฐ๊ฐ์ด z
๋ผ๊ณ ํ๋ค๋ฉด,
๊ฐ๊ฐ์ ํจ์๋ ๋ค์๊ณผ ๊ฐ์ ํํ๋ฅผ ๊ฐ์ง๋๋ค.
{- foldl (left associative) -}
f ( ... (f (f (f (f z x1) x2) x3) x4) ...) xn
{- foldr (right associative) -}
f x1 (f x2 (f x3 (f x4 ... (f xn z) ... )))
๋ ํจ์ ๋ชจ๋ lazy
ํ๊ฒ ํ๊ฐ๋๋ค๋ ๊ฒ์ ๋์ผํฉ๋๋ค.
๋ค๋ง ์์์ ๋ณผ ์ ์๋ฏ์ด foldl
์ ๊ฒฐ๊ณผ ๊ฐ์ ์ป๊ธฐ ์ํด ์ค์ฒฉ๋ ๋ชจ๋ ๋ฆฌ์คํธ๋ฅผ ํ์ํด์
์ต์ข
ํํ์์ ๋ง๋ค์ด์ผํ๊ธฐ์ ์ด๋ ๊ณณ stack overflow
๋ฅผ ๋ฐ์์ํค๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ฉด foldr
์ f
๊ฐ ์ ์ฉ๋ ํ๋์ ์์ + ๋๋จธ์ง infinite list ๋ก ๋ถ๋ฆฌํ์ฌ ์ ์ฉ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์
๋ฌธ์ ์์ด ๋์ํ๊ฒ ๋ฉ๋๋ค.
foldl versus foldr behavior with infinite lists
Haskell, foldr on infinite list
scanl, scanr ์ดํด๋ณด๊ธฐ
์ด ๋ ํจ์๋ ์์ ์ค๋ช
ํ fold
ํจ์์ ํฌ๊ฒ ๋ค๋ฅด์ง ์์ต๋๋ค.
์ฐจ์ด์ ์ scan
ํจ์๋ ์ค๊ฐ ๋์ ๊ฐ๋ค์ ๊ฒฐ๊ณผ ๋ฐฐ์ด์ ํฌํจ์์ผ์ค๋ค๋ ๊ฒ์
๋๋ค.
ghci> scanl (+) 0 [1, 2, 3, 4]
[0,1,3,6,10]
ghci> scanr (+) 0 [1, 2, 3, 4]
[10,9,7,4,0]
์ํ๋ฅผ ํ๋ ๋ฐฉํฅ์ ๋ฐ๋ผ ์ต์ข ๊ฒฐ๊ณผ๊ฐ์ด ๋ด๊ธฐ๋ ์์น๊ฐ ๋ฌ๋ผ์ง๋๋ค.
fold
๊ณผ์ ์ด ์ด๋ป๊ฒ ์ด๋ฃจ์ด์ง๋์ง ํ์ธํ ๋ ์ ์ฉํ ๊ฒ ๊ฐ์ต๋๋ค.
๐ Function application with $
Haskell
์์ ์ผ๋ฐ์ ์ผ๋ก ํจ์๋ left-associative
ํฉ๋๋ค.
๋ฐ๋ผ์ ๋ค์์ฝ๋์ ๊ฒฐ๊ณผ๋ 15
์
๋๋ค.
ghci> sqrt 4 + 4 + 9
15.0
-- ์ ํํ์์ ๋ค์๊ณผ ๋์ผํฉ๋๋ค.
ghci> (((sqrt 4) + 4) + 9)
15.0
๋ง์ฝ 4+4+9
์ ์ ๊ณฑ๊ทผ์ ๊ตฌํ๊ณ ์ถ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ดํธ๋ฅผ ์ฌ์ฉํด์
์ฐ์ฐ์ ์ฐ์ ์์๋ฅผ ๋ถ์ฌํด์ผํ ๊ฒ๋๋ค.
ghci> sqrt (4 + 4 + 9)
4.123105625617661
์ด๋ด๋ ๊ฐ์ฅ ๋ฎ์ ์ฐ์ฐ์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๋ $
๋ฅผ ์ด์ฉํ๋ฉด
right-associative
ํ ์ฐ์ฐ์ ๊น๋ํ๊ฒ ์ํํ ์ ์์ต๋๋ค.
์ด๋ฅผ ํตํด ์์์ ๊ดํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํ ๋์์ ๊ตฌํํ ์ ์์ต๋๋ค.
ghci> sqrt $ 4 + 4 + 9 -- โ
์ด๊ฑฐ๋ sqrt (4 + 4 + 9) ์ ๋์ผํ๋ค
4.123105625617661 -- 17 ์ ์ ๊ณฑ๊ทผ
๐ ํฉ์ฑ ํจ์
ํฉ์ฑํจ์ ํํ
ํฉ์ฑํจ์๋ ๋ค์๊ณผ ๊ฐ์ด ํํํฉ๋๋ค.
์ฆ ๋ ํจ์ g, f ๊ฐ ์ฐ์์ ์ผ๋ก ํธ์ถ๋ ๋ h
๋ฅผ g ์ f ์ ํฉ์ฑํจ์
๋ผ๊ณ ํํํฉ๋๋ค.
Haskell
์์ ํฉ์ฑํจ์๋ ๋ค์๊ณผ ๊ฐ์ ํ์
์ ๊ฐ์ง๋๋ค.
ghci> :type (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
์ฐ๋ฆฌ๋ ์ด๋ฏธ ํจ์๊ฐ left-associative
ํ๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค.
๋ฐ๋ผ์ ์ ํ์ ์ ๋ค์๊ณผ ๊ฐ์ด ํํํ ์ ์์ ๊ฒ์ ๋๋ค.
(.) :: (b -> c) -> (a -> b) -> (a -> c)
ํ์ ์ ๋ค์ ๋ณด๋ฉด 2๊ฐ์ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ์ ์๋ก์ด ํจ์๋ฅผ ๋ฐํํ๋ ๊ฒ์ผ๋ก ๋ณด์ด์ง ์๋์?
์ด๋ฅผ ๋์ํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
a
๋ผ๋ ์ ๋ค๋ฆญ ํ์
์ด c
๋ผ๋ ์ ๋ค๋ฆญ ํ์
์ผ๋ก ๋ฐ๋๊ธฐ ์ํด
๋ ๊ฐ์ ํจ์ g ์ f
๋ฅผ ๊ฑฐ์น๋ฉฐ ์ด๋ h
๋ผ๋ ์๋ก์ด ํจ์๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
ํฉ์ฑํจ์์ ์ฐ์์
ํฉ์ฑํจ์๋ ๋๋คํจ์๋ก ๋๊ฒจ์ฃผ๋ ๊ฒ์ ์ข ๋ ์ง๊ด์ ์ธ ํํ
๋ก ๋ฐ๊พธ๋๋ฐ ์ ์ฉํฉ๋๋ค.
์์๋ฅผ ์ํด ๋ค์๊ณผ ๊ฐ์ ํจ์๊ฐ ์๋ค๊ณ ํ๊ฒ ์ต๋๋ค.
ghci> map (\xs -> negate (sum (tail xs))) [[1..5],[3..6],[1..7]]
[-14,-15,-27]
์ด ํจ์๋ ์์ ๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ์์(head) ๋ฅผ ์ ์ธํ ๋๋จธ์ง ๊ฐ๋ค์ ํฉ์ ์์๊ฐ ๋ฐฐ์ด์ ๋ง๋ค์ด ๋ฐํํฉ๋๋ค.
์ด์ ์ด ํจ์๋ฅผ ํฉ์ฑํจ์๋ฅผ ์ด์ฉํด์ ๊ฐ๋จํ๊ฒ ํํํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ ํฉ์ฑํจ์์ ์ ์๋ฅผ ๋ค์ ํ๋ฒ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ํฉ์ฑํจ์์ ํน์ฑ์ ์ด์ฉํด์ ์ฐ๋ฆฌ๋ g
์ ์ ์ฉ๋๋ ์ธ์ x
๋ฅผ ํฉ์ฑํจ์ f*โ*g
์ ์ธ์๋ก ๋ฐ๊ฟ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ์ ํจ์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
ghci> map (\xs -> (negate . sum . tail) xs) [[1..5],[3..6],[1..7]]
์ฌ๊ธฐ์ eta conversion
์ ์ฌ์ฉํ๋ฉด ๋๋คํจ์๋ฅผ ์ ๊ฑฐํ ์ ์์ต๋๋ค.
์ด๋ฅผ ํตํด pointless style
๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
ghci> map (negate . sum . tail) [[1..5],[3..6],[1..7]]
๐ก (์ฐธ๊ณ ) point free style ์ด๋?
์๋ฌต์ ํ๋ก๊ทธ๋๋ฐ (Tacit programming) ์ผ๋ก ๋ถ๋ฆฌ๋ ์ด ๋ฐฉ์์
ํจ์ ์ ์๊ฐ ์ธ์๋ฅผ ์๋ณํ์ง ์๋๋ก ํ๋ ์ ์ ํ ์ถ์ํ๋ฅผ ์ง์ํ๋๋ก ํฉ๋๋ค.
์ด๋ฅผ ํตํด ๋ณํ์ ์ฌ์ฉ๋๋ ์ธ์ ๋์ ์ ๋ณํ ๊ทธ ์์ฒด์ ์ข ๋ ์ง์คํ ์ ์์ต๋๋ค.
๋ํ ๋ฑ์ ์ถ๋ก
์ ์์ฐ์ค๋ฝ๊ฒ ๋ง๋๋ ๊ตฌ์กฐํ๋ ์กฐํฉ ์คํ์ผ์ ๊ฐ์ํ๋ค๋ ์ฅ์ ๋ ์์ต๋๋ค.
sum lst = foldr (+) 0 lst
sum = foldr (+) 0
โ ๏ธ ์ ์ํ ์
๋ค๋ง ํฉ์ฑํจ์๋ฅผ ์ฌ์ฉํ ๋ ๊ฐ๊ฐ์ ํจ์๊ฐ ๋ณต์กํด์ง๊ณ ์ฒด์ด๋์ด ๊ธธ์ด์ง์๋ก
์ด ํจ์๊ฐ ์ด๋ค ์๋์ ์ํด ์ด๋ ๊ฒ ๊ธธ์ด์ง๊ฑด์ง ๋งฅ๋ฝ ํ์ ์ด ํ๋ค์ด์ง ์ ์์ต๋๋ค.
์ด๋๋ let binding
์ ์ด์ฉํ๋ฉด ์๋ฏธ์๋ ๋ ์์ ๋จ์์ ๋ ์ด๋ธ๋ง๋ ํจ์๋ก ์ชผ๊ฐค ์ ์์ต๋๋ค.
oddSquareSum =
let oddSquares = filter odd $ map (^2) [1..]
belowLimit = takeWhile (<10000) oddSquares
in sum belowLimit
๐ ์ฐธ๊ณ ์๋ฃ
Higher Order Functions - Learn You a Haskell for Great Good!
'๐ archive' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Haskell Tutorial] Data Type (0) | 2022.12.31 |
---|---|
[Haskell Tutorial] Recursion (0) | 2022.12.31 |
[Haskell Tutorial] Module (0) | 2022.11.28 |
[Haskell Tutorial] Type (0) | 2022.11.28 |
[Haskell Tutorial] Function & Chaining (0) | 2022.11.28 |
๐ฌ ๋๊ธ