Folding in Haskell π
μ·¨μ
μ μν ν¬νΈν΄λ¦¬μ€ μ€λΉ μμ
μΌλ‘ λ°μ κ°μ΄λ°, Functional
Programmingμ λν΄ κ΄μ¬μ΄ μ겨 Haskell
μ΄λΌλ μΈμ΄λ₯Ό λ°°μ°κΈ°
μμνλ€. (μκ³ λ¦¬μ¦μ΄λ λ°μ΄ν°λ² μ΄μ€ λ± λ°°μΈ κ²μ΄ λ§μ λ° κ°μλ‘
νμ°μ΄λ€.) λνκ΅ μμ , xmonad μλμ°μ¦ 맀λμ λ₯Ό μ¬μ©νλ©΄μ μ ν
μΈμ΄λ₯Ό μ΄λ κ² λ€λ¦κ² λ°°μ°κ² λ μ€μ κΏμλ λͺ°λλ€.
λνμ μΈ ν¨μν μΈμ΄λ‘ μλ €μ§ Haskell μλ Folding
μ΄λΌλ νΉλ³ν
κ°λ
μ΄ λ±μ₯νλ€. Haskell Wiki
μμλ Folding
μ μλμ κ°μ΄ μ€λͺ
νκ³
μλ€.
In functional programming, fold (or reduce) is a family of higher order functions that process a data structure in some order and build a return value.
Typically, a fold deals with two things: a combining function, and a data structure (typically a list of elements). The fold then proceeds to combine elements of the data structure using the function in some systematic way.
리μ€νΈμ κ°μ΄ μ¬λ¬ μμλ€λ‘ μ΄λ£¨μ΄μ§ λ°μ΄ν° ꡬ쑰μ κ° μμλ€μ κ°κ°
μΈμ(arguments)λ‘ λκΈ΄ ν¨μμ λμ
νκ³ , κ·Έ κ²°κ³Όλ₯Ό μμ νμ
μΌλ‘
λ°ννλ κ²μ΄ fold
ν¨μμ μν μ΄λ€. λ€μ λ§ν΄μ, spine
ννμ
λ°μ΄ν° ꡬ쑰λ₯Ό νΉμ ν ν¨μλ₯Ό μ΄μ©νμ¬ μ κ³ (fold
) μ€μ¬μ(reduce
)
κ²°κ³Όκ°μ μ»λ κ²μ΄ κ·Έ μν μ΄λΌκ³ μ 리νλ©΄ μ΄ν΄νκΈ° μ½λ€.
λ¨Όμ , μλμ μμ λ₯Ό μ΄ν΄λ³΄μ.
> foldr (+) 1 [1..3]
7
> :t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
foldr
μ (a -> b -> b)
ννμ ν¨μμ b
, t a
μΈμ 3 κ°λ₯Ό μ
λ ₯
λ°μ b
νμ
μ λ°ννλ€. μ¦, (1 + (2 + (3 + (1))) κ³Ό κ°μ νμμΌλ‘
fold
λ₯Ό μ§ννμ¬ κ²°κ΅ λ΅μ 7μ΄ λλ€. μ΄ λ, κ° κ΄νΈλ₯Ό reduceν
κ²°κ³Όλ foldr
λμ scanr
ν€μλλ₯Ό μ¬μ©νλ©΄ μλμ κ°μ΄ μ»μ μ
μλ€.
> scanr (+) 1 [1..3]
[7,6,4,1]
κ·Έλ λ€λ©΄, λ°λλ‘ κ΄νΈλ₯Ό μμ§μ¬ evaluationμ λ°©ν₯μ μΌμͺ½μμ μ€λ₯Έμͺ½μΌλ‘ λ°κΏλ³΄λ©΄ μ΄λ¨κΉ?
> foldl (+) 1 [1..3]
7
> scanl (+) 1 [1..3]
[1,2,4,7]
> :t foldl
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
foldr
κ³Ό λ¬λ¦¬ foldr
μ μ λ¬ν ν¨μμ μΈμλ‘ (a -> b -> b)
κ° μλ
(b -> a -> b)
λ₯Ό μ λ¬νλ€. μ΄ λλ¬Έμ κ²°κ³Όκ°μ κ°λλΌλ
νκ°(Evaluation)μ μμκ° ((((1) + 1) + 2) + 3) λ¬λΌμ§κ² λλ€. μ΄
λλ¬Έμ scanl
μ κ²°κ³Όλ [1,2,4,7]
μ΄ λλ κ²μ΄λ€.
μ΄λ¬ν fold
μ μ₯μ μ κ°κ°μ§ μ¬κ· ν¨μλ€μ μμ²λκ² κ°λ¨νκ² λ§λ€ μ
μλ€λ κ²μ΄λ€. μλ₯Ό λ€λ©΄, reverse ν¨μμ κ²½μ° λ³΄ν΅ μλμ κ°μ΄ μμ±ν
μ μλ€.
myReverse :: [a] -> [a]
myReverse [] = []
myReverse (x:xs) = myReverse xs ++ [x]
νμ§λ§, fold
λ₯Ό μ¬μ©νλ©΄, μλμ κ°μ΄ μΆμ½λ ννλ‘ κ°λ¨νκ² μμ±ν
μ μλ€.
-- pointfree ν¨μ ννλ‘ μμ±
myReverse :: [a] -> [a]
myReverse = foldl (flip (:)) []
μ΄μ²λΌ ν¨μν νλ‘κ·Έλλ°μμ fold
λλ reduce
λ μΈμλ‘ μ λ¬ν
λ°μ΄ν° ꡬ쑰λ₯Ό νΉμ ν ν¨μλ₯Ό μ΄μ©νμ¬ λ°νκ°μ ꡬμ±νκΈ° μν HOF
(Higher Order Functions, ν¨μλ₯Ό μΈμλ‘ μ·¨νκ±°λ λ°νκ°μΌλ‘ ν¨μλ₯Ό
λ°ννλ ν¨μ)μ ν κ°μ§μ΄λ€. λ¬Έμ λλΆλΆμ΄ μμ΄λ‘ λμ΄ μκ³ ν¨μν
μΈμ΄μ λν΄μλ μμ§κΉμ§ κ΄μ¬μ κ°μ§λ μ¬λμ΄ λ§μ΄ μμ΄ κ³΅λΆνκΈ°μλ
μ½μ§ μμ§λ§ νλμ© μ λ¦¬ν΄ λκ°λ€ 보면 μΈμ κ°λ λ¬Έμλ₯Ό λ§λ€ μ μμ
μ λλ‘ μλ£κ° λ§μμ§ κ²μ΄λΌ κΈ°λνλ€.