์ด๋ฒ ํฌ์คํธ๋ 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
Eta conversion - HaskellWiki
<!-- Saved in parser cache with key wikidb_haskell:pcache:idhash:2670-0!canonical and timestamp 20221230200441 and revision id 63978 -->
wiki.haskell.org
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
foldl versus foldr behavior with infinite lists
The code for the myAny function in this question uses foldr. It stops processing an infinite list when the predicate is satisfied. I rewrote it using foldl: myAny :: (a -> Bool) -> [a] -> Bool m...
stackoverflow.com
Haskell, foldr on infinite list
Haskell, foldr on infinite list
I got a question while reading LYAH. Here is my thought of foldr on infinite list: foldr (:) [] [1..] = 1:2:...:**∞:[]** I think GHCi does not know it is list before evaluating ∞:[]. But GHCi d...
stackoverflow.com
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
Pointfree - HaskellWiki
Pointfree Style It is very common for functional programmers to write functions as a composition of other functions, never mentioning the actual arguments they will be applied to. For example, compare: with: These functions perform the same operation, howe
wiki.haskell.org
โ ๏ธ ์ ์ํ ์
๋ค๋ง ํฉ์ฑํจ์๋ฅผ ์ฌ์ฉํ ๋ ๊ฐ๊ฐ์ ํจ์๊ฐ ๋ณต์กํด์ง๊ณ ์ฒด์ด๋์ด ๊ธธ์ด์ง์๋ก
์ด ํจ์๊ฐ ์ด๋ค ์๋์ ์ํด ์ด๋ ๊ฒ ๊ธธ์ด์ง๊ฑด์ง ๋งฅ๋ฝ ํ์ ์ด ํ๋ค์ด์ง ์ ์์ต๋๋ค.
์ด๋๋ 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 |
๐ฌ ๋๊ธ