[λ²μ] νλ‘κ·Έλλ¨Έλ₯Ό μν μΉ΄ν κ³ λ¦¬ μ΄λ‘ - 7. νν°
μ΄λ² μ±ν°μμλ νν°(Functor)μ λν΄μ μ΄μΌκΈ°λ₯Ό ν΄λ³΄λ €κ³ νλ€. νν°λ κ°λ¨νμ§λ§ λ§€μ° κ°λ ₯ν κ°λ μ΄λ©° μΉ΄ν κ³ λ¦¬ μ΄λ‘ μ μ΄μ²λΌ κ°λ¨νμ§λ§ κ°λ ₯ν μμ΄λμ΄λ‘ κ°λ μ°¨μλ€.
νν°λ μΉ΄ν κ³ λ¦¬ κ°μ 맀νμ΄λ€. μ¦, λ μΉ΄ν κ³ λ¦¬ μ κ° μ£Όμ΄μ‘μ λ, νν° λ μΉ΄ν κ³ λ¦¬ μ λμμ μΉ΄ν κ³ λ¦¬ μ λμμΌλ‘ 맀ννλ κ²μ΄λ©°, κ²°κ΅ λμλ€μ λν ν¨μλΌκ³ λ³Ό μ μλ€.
λ§μ½ μΉ΄ν κ³ λ¦¬ μ λμμ λΌκ³ νλ€λ©΄, μ°λ¦¬λ 맀νλ μΉ΄ν κ³ λ¦¬ μ λμμ λΌκ³ ννν μ μλ€. νμ§λ§ μΉ΄ν κ³ λ¦¬λ λμμΌλ‘λ§ κ΅¬μ±λμ΄μμ§ μμΌλ©° λμκ³Ό κ·Έλ€μ μ°κ²°νλ μ¬μκΉμ§ λͺ¨λ ν¬ν¨νλ κ°λ μ΄λ€. μ¦, νν°λ λμ λΏ μλλΌ μ¬μ λν 맀ννλ©°, μ΄λ° κ²½μ°μλ μ¬μμ λν ν¨μλΌκ³ λ³Ό μλ μλ€. κ·Έλ λ€κ³ νν°κ° λ§μλλ‘ μ¬μμ 맀ννλ κ²μ μλκ³ , λ°λμ μ¬μμΌλ‘ μ°κ²°λ λμλ€μ ꡬ쑰λ₯Ό κ·Έλλ‘ λ³΄μ‘΄ν΄μΌ νλ€.
λ§μ½ μΉ΄ν κ³ λ¦¬ μ μλ μ¬μ κ° λμ μ λ₯Ό μ°κ²°νκ³ μλ€λ©΄,
f :: a -> b
νν°λ₯Ό ν΅ν΄ 맀νλ μΉ΄ν κ³ λ¦¬ μ μλ μ¬μ μΈ λν μ λμΌν κ΅¬μ‘°λ‘ λμ μ λ₯Ό μ°κ²°ν΄μΌ νλ€.
F f :: F a -> F b
μ¬κΈ°μ μ μ μλ―μ΄ νν°λ μΉ΄ν κ³ λ¦¬μ ꡬ쑰λ₯Ό κ·Έλλ‘ λ³΄μ‘΄νλ€. ν μΉ΄ν κ³ λ¦¬ λ΄μμ μ°κ²°λμ΄μλ κ²λ€μ νν°λ₯Ό ν΅ν΄ 맀νλ μΉ΄ν κ³ λ¦¬μμλ κ·Έλλ‘ μ°κ²°λμ΄ μλ κ²μ΄λ€. μ΄μ λν΄ μΉ΄ν κ³ λ¦¬μλ λ¨μν λμμ μ¬μμΌλ‘ μ°κ²°νλ κ² λΏ μλλΌ μ¬μ κ°μ ν©μ±μ΄λΌλ κ°λ λν μ‘΄μ¬νλ€.
μ¬μ κ° μ μ ν©μ±μ¬μμΈ μν©μ μκ°ν΄λ³΄μ.
h = g . f
κ·Έλ λ€λ©΄ νν° λ₯Ό ν΅ν΄ λ§λ€μ΄μ§ μΉ΄ν κ³ λ¦¬μ μ¬μλ€μ ν©μ± κ΄κ³λ μ΄μ λμΌνκ² μ μ§λλ€.
F h = F g . F f
λ§μ§λ§μΌλ‘ μ°λ¦¬λ μΉ΄ν κ³ λ¦¬ μμ λͺ¨λ νλ±μ¬μλ€μ΄ μΉ΄ν κ³ λ¦¬ μ νλ±μ¬μλ€λ‘ 맀νλλ μν© λν μκ°ν΄λ³Ό μ μλ€.
F id_a = id_Fa
μ¬κΈ°μ λ λμ μ νλ±μ¬μμ΄λ©°, λ λμ μ νλ±μ¬μμ΄λ€. μ΄μ²λΌ νμ μΉ΄ν κ³ λ¦¬μ ꡬ쑰λ₯Ό 보쑴ν΄μΌνλ€λ 쑰건λ€λ‘ μΈν΄ νν°λ μΌλ°μ μΈ ν¨μλ³΄λ€ λ μ νμ μΈ κ°λ μ΄ λλ€.
λ§μ½ μ΄λ€ μΉ΄ν κ³ λ¦¬λ₯Ό κ° λμλ€μ΄ μ¬μμΌλ‘ μ°κ²°λμ΄μλ μΌμ’ μ λ€νΈμν¬λΌκ³ μμν΄λ³΄μ. νν°λ κ° λμκ³Ό μ¬μμ κ·Έμ 맀ννλ κ°λ μΌλΏμ΄λ―λ‘ λ€νΈμν¬μ μμλ€μ μλ‘ λΆλ¦¬ν΄λ΄λ κ²μ μ λ λΆκ°λ₯νλ€. νν°λ‘ λμλ€μ ν©μΉ μλ μκ³ μ¬λ¬ μ¬μλ€μ νλλ‘ λΆνλμ μλ μκ² μ§λ§ λΆν΄νλ κ²μ λΆκ°λ₯ν κ²μ΄λ€.
μ΄μ κ°μ΄ λΆν΄κ° λΆκ°λ₯νλ€λ μ μ½μ λ―Έμ λΆμμ λ³Ό μ μλ μ°μμ±μ 쑰건과 μ μ¬νλ€. μ΄λ° μλ―Έμμ νν°λ βμ°μμ βμ΄λΌκ³ λ³Ό μλ μλ€. λν λ§μΉ μ μμκ³Ό 곡μμ κ΄κ³λ₯Ό μΆμλ ν¬ν¨μ΄λΌλ μκ°μΌλ‘ λ°λΌλ³΄λ κ²κ³Ό μ μ¬νκ² νν° λν λμΌν μκ°μΌλ‘ λ°λΌλ³Ό μ μλ€. μλ₯Ό λ€λ©΄ νν°μ μμ€κ° λλ μΉ΄ν κ³ λ¦¬κ° λμ μΉ΄ν κ³ λ¦¬λ³΄λ€ λ μμ λλ ν¬ν¨κ³Ό κ°μ κ°λ μΌλ‘ λ³Ό μ μλ κ²μ΄λ€.
νλ² κ·Ήλ¨μ μΈ μμλ₯Ό μκ°ν΄λ³΄μ. νν°μ μμ€κ° λλ μΉ΄ν κ³ λ¦¬λ λ¨ νλμ λμκ³Ό νλμ νλ±μ¬μλ§μΌλ‘ μ΄λ£¨μ΄μ§ λ¨μΌλμ μΉ΄ν κ³ λ¦¬κ° λ μλ μλ€. μ΄μ²λΌ λ¨μΌλμ μΉ΄ν κ³ λ¦¬λ₯Ό λ€λ₯Έ μΉ΄ν κ³ λ¦¬λ‘ λ§€ννλ νν°λ λ¨μν ν΄λΉ μΉ΄ν κ³ λ¦¬μμ νλμ λμμ μ ννλ κ²κ³Ό λ€λ₯Ό κ² μλ€. μ΄λ λ¨μΌμμμ§ν©μμ νλμ μμλ₯Ό μ ννλ μ¬μμ νΉμ±κ³Ό μμ ν μ μ¬νλ€.
μμ€ μΉ΄ν κ³ λ¦¬λ₯Ό μ΅λν μΆμνλ νν°λ μμ νν°(Constant Functor), λ‘ λΆλ¦°λ€. μ΄ νν°λ μμ€ μΉ΄ν κ³ λ¦¬μ λͺ¨λ λμμ λμ μΉ΄ν κ³ λ¦¬μμ μ νλ νλμ λμμΈ λ‘, κ·Έλ¦¬κ³ μμ€ μΉ΄ν κ³ λ¦¬μ λͺ¨λ μ¬μμ νλ±μ¬μμΈ λ‘ λ§€ννλ€. μ΄ νν°λ λ§μΉ λΈλνμ²λΌ μλνμ¬ λͺ¨λ κ²μ νλμ νΉμ΄μ μΌλ‘ μμΆν΄λ²λ¦°λ€. μ°λ¦¬κ° μΆν νκ³(Limits)μ 곡νκ³(Colimits)μ λν΄ μ΄μΌκΈ°ν λ μ΄λ¬ν νν°λ₯Ό λ μμΈν μ΄ν΄λ³Ό κ²μ΄λ€.
π‘ μμ£Ό
μκ°μ μ€λͺ λ§ λ³΄λ©΄ λ§μΉ μμ νν°()κ° μ΄λ€ μΉ΄ν κ³ λ¦¬λ₯Ό λ€λ₯Έ μΉ΄ν κ³ λ¦¬λ‘ λ§€ννλ©° μμΆνλ λ μμΌλ‘ λ³΄μΌ μ μμ§λ§, μ¬μ€ μμ νν°λ νΉμ μΉ΄ν κ³ λ¦¬λ₯Ό μκΈ° μμ μΌλ‘ 맀ννλ μλνν°(EndoFunctor)μ΄λ€. (μλνν°μ λν μ€λͺ μ λ°λ‘ λ€μ μΉμ μ λμ¨λ€.)
μ¦, μμ νν°λ μ΄λ€ μΉ΄ν κ³ λ¦¬μ λͺ¨λ λμμ κ·Έ μΉ΄ν κ³ λ¦¬ λ΄μ λμ νλλ‘ λ§€ν(μμΆ)νλ κ°λ μ΄λΌκ³ 보면 λλ€. μ΄ κ³Όμ μμ μΉ΄ν κ³ λ¦¬μ λμλ€μ μ°κ²°νλ μμμ μ¬μλ€μ λͺ¨λ μ νλ λμμ νλ± μ¬μμΌλ‘ 맀νλλ€.
7.1 νλ‘κ·Έλλ°μμμ νν°
μ΄μ λΆν°λ μ€μ§μ μΈ νλ‘κ·Έλλ°μ λν΄μ μ΄μΌκΈ°ν΄λ³΄μ. μ΄λ―Έ μ°λ¦¬λ νλ‘κ·Έλλ°μ μΈκ³μμ νμ κ³Ό ν¨μλ‘ μ΄λ£¨μ΄μ§ μΉ΄ν κ³ λ¦¬λ₯Ό λ€λ£¨κ³ μλ€. μ΄λ²μλ μ΄ μΉ΄ν κ³ λ¦¬λ₯Ό μκΈ° μμ μΌλ‘ 맀ννλ νν°, μλνν°(EndoFunctor)μ λν΄μ μκ°ν΄λ³΄λ €κ³ νλ€.
μ, νμ μΌλ‘ μ΄λ£¨μ΄μ§ μΉ΄ν κ³ λ¦¬μμμ μλνν°λ 무μμΌκΉ? μ΄ νν°λ νμ μ νμ μΌλ‘ 맀ννλ νν°μΌ κ²μ΄λ€. μ¬μ€ μ¬λ¬λΆμ μ΄λ―Έ μ΄λ¬ν 맀νμ μμλ₯Ό μ±νκ² λ΄μμν μ§λ§ λ¨μ§ κ·Έκ²μ΄ μλνν°λΌλ κ²μ κΉ¨λΏμ§ λͺ» νμ λΏμ΄λ€. μλ λͺ κ°μ§ μμλ₯Ό νλ² μ΄ν΄λ³΄μ.
7.1.1 Maybe νν°
Maybe
μ μ μλ μ΄λ ν νμ
a
λ₯Ό Maybe a
λΌλ νμ
μΌλ‘ 맀ννλ κ²μ΄λ€.
data Maybe a = Nothing | Just a
μ¬κΈ°μ μ€μν ν¬μΈνΈκ° νλ μλ€. Maybe
μ체λ νμ
μ΄ μλλΌ νμ
μμ±μ(Type Constructor)λΌλ κ²μ΄λ€. νμ
μμ±μλ₯Ό νμ
μΌλ‘ λ³ννκΈ° μν΄μλ Int
λ Bool
κ³Ό κ°μ νμ
μΈμλ₯Ό μμ±μμκ² μ 곡ν΄μΌ νλ€. μ¦, μ무 μΈμλ‘ λ°μ§ μλ Maybe
λ νμ
μ λν ν¨μλ₯Ό λνλ΄λ κ²μ΄λ€.
κ·Έλ λ€λ©΄ Maybe
λ₯Ό νν°λ‘ λ³νν΄λ³Ό μ μμκΉ? (νλ‘κ·Έλλ° λ§₯λ½μμ νν°μ λν΄ μ΄μΌκΈ°ν λλ κ±°μ νμ μλνν°λ₯Ό μ΄μΌκΈ°νλ€λ μ¬μ€μ μ λ
νμ.) νν°λ λμ(νμ
)μ 맀ν λΏλ§ μλλΌ μ¬μ(ν¨μ)μ 맀νλ λͺ¨λ ν¬ν¨νλ κ°λ
μ΄λ€. νλ² a
μμ b
λ‘ λμκ°λ μμμ ν¨μ f
κ° μλ€κ³ μκ°ν΄λ³΄μ.
f :: a -> b
μ°λ¦¬λ Maybe a
μμ Maybe b
λ‘ λμκ°λ ν¨μλ₯Ό μμ±νκ³ μΆλ€. μ΄λ¬ν ν¨μλ₯Ό μ λλ‘ μ μνκΈ° μν΄μλ Maybe
λ₯Ό ꡬμ±νλ λ μμ±μμΈ Nothing
κ³Ό Just
μ λν΄ κ³ λ €ν΄μΌνλ€.
Nothing
μ κ²½μ°μλ κ·Έμ Nothing
μ λ°νν΄μ£ΌκΈ°λ§ νλ©΄ λλ κ°λ¨νλ€. κ·Έλ¦¬κ³ μΈμκ° Just
μΈ κ²½μ°μλ ν¨μ f
λ₯Ό Just
κ° κ°μ§κ³ μλ κ°μ μ μ©ν΄μ£Όλ©΄ λ κ²μ΄λ€.
μ¦, Maybe
λΌλ νν°λ₯Ό κ±°μΉ f
μ λͺ¨μ΅μ μλμ κ°μ ν¨μκ° λλ€. (Haskellμμλ λ³μλͺ
μ μν¬μ€νΈλ‘νΌ(β
)λ₯Ό μ¬μ©ν μ μμΌλ©°, μ΄ κΈ°λ₯μ μλμ κ°μ κ²½μ°μ λ§€μ° νΈλ¦¬νλ€.)
f' :: Maybe a -> Maybe b
f' Nothing = Nothing
f' (Just x) = Just (f x)
Haskellμμλ νν°κ° μ¬μμ 맀ννλ νμλ₯Ό fmap
μ΄λΌλ κ³ μ°¨ν¨μλ‘ κ΅¬ννλ©°, Maybe
μ κ²½μ°μλ μλμ κ°μ μ μκ° λ κ²μ΄λ€.
fmap :: (a -> b) -> (Maybe a -> Maybe b)
μ°λ¦¬λ μ’
μ’
fmap
μ΄ ν¨μλ₯Ό 리ννΈ(lift)νλ€κ³ λ§νλ€. μ΄λ κ² λ¦¬νν
λ ν¨μλ μ΄μ Maybe
νμ
μ κ°μ μμ©νλ ν¨μκ° λμλ€.
λν 컀λ§(Currting)μΌλ‘ μΈν΄ μ μ μλ νλμ ν¨μ a β b
λ₯Ό λ°μμ λ€λ₯Έ ν¨μ Maybe a β Maybe b
λ₯Ό λ°ννλ ν¨μ, κ·Έλ¦¬κ³ a β b
μ Maybe a
λΌλ λ κ°μ μΈμλ₯Ό λ°μ Maybe b
λ₯Ό λ°ννλ ν¨μ, μ΄ λ κ°μ§ λ°©μμΌλ‘ ν΄μλ μ μλ€.
fmap :: (a -> b) -> Maybe a -> Maybe b
μ΄λ¬ν νΉμ±λ€μ κΈ°λ°μΌλ‘ Maybe
μ λν fmap
μ ꡬνν΄λ³΄λ©΄ μλμ κ°λ€.
fmap _ Nothing = Nothing
fmap f (Just x) = Just (f x)
-- μ μ©ν ν¨μ fμ Just xλ₯Ό μΈμλ‘ λ°μ,
-- Justκ° κ°μ§ κ°μ ν¨μ fκ° μ μ©λ κΌ΄μΈ Just (f x)λ₯Ό λ°ννλ€.
μ°λ¦¬κ° Maybe
νμ
μμ±μμ fmap
ν¨μκ° νν°λ₯Ό νμ±νλ€λ κ²μ 보μ΄κΈ° μν΄μλ fmap
ν¨μκ° νλ±κ³Ό ν©μ±μ κ°λ
μ 보쑴νλ€λ κ²μ μ¦λͺ
ν΄μΌνλ€. μ΄λ¬ν κ²λ€μ βνν° λ²μΉ(The Functor Laws)βμ΄λΌλ κ±°μ°½ν μ΄λ¦μΌλ‘ λΆλ₯΄κΈ΄ νμ§λ§ μ¬μ€μ κ·Έμ νν°κ° μΉ΄ν
κ³ λ¦¬μ ꡬ쑰λ₯Ό 보쑴νλ€λ κ²μ 보μ₯ν΄μΌνλ€λ μλ―Έμ΄λ€.
7.1.2 λ°©μ μ μΆλ‘ (Equational Reasoning)
νν° λ²μΉμ μ¦λͺ νκΈ° μν΄ λ°©μ μ μΆλ‘ (Equational Reasoning)μ μ¬μ©ν΄λ³΄λ €κ³ νλ€. μ΄λ Haskellμμ ννκ² μ¬μ©λλ μ¦λͺ κΈ°λ²μΈλ°, Haskell ν¨μκ° μ’λ³μ΄ μ°λ³κ³Ό κ°λ€λ λλ±μ±(Equality)μΌλ‘ μ μλλ€λ μ¬μ€μ μ΄μ©νλ κΈ°λ²μ΄λ€. μ΄λ€ μ½λλ₯Ό λμμ΄ λμΌν λ€λ₯Έ μ½λλ‘ λ체ν μλ μκ³ λ³μλͺ μ μΆ©λμ νΌνκΈ° μν΄ λ³μλͺ μ λ³κ²½ν μλ μλλ°, μ΄λ ν¨μλ₯Ό μΈλΌμΈννλ νμλ λ°λλ‘ ννμμ ν¨μλ‘ λ¦¬ν©ν λ§νλ νμλ‘ μκ°ν μλ μλ€. νλ² νλ±ν¨μλ₯Ό μμλ‘ μ΄ν΄λ³΄μ.
id x = x
μ΄λ¬ν ν¨μκ° μ‘΄μ¬νλ€λ©΄ μ΄μ μ°λ¦¬λ μ΄λ€ ννμμμ id y
λ₯Ό 보μμ λ, μ΄ μ½λλ₯Ό y
λ‘ λ°κΏλ³Ό μ μλ€(μΈλΌμΈν). λ λμκ°μ id (y + 2)
μ κ°μ΄ id
κ° ννμμ μ μ©λμ΄μλ€λ©΄ μ΄λ₯Ό ννμ κ·Έ μμ²΄μΈ (y + 2)
λ‘ λ°κΏ μλ μλ€. λν μ΄ μΉνμ μλ°©ν₯μΌλ‘ μ μ©λκΈ° λλ¬Έμ ννμ e
λ₯Ό id e
λ‘ μΉνν μλ μλ€.(리ν©ν λ§)
ν¨μκ° ν¨ν΄ 맀μΉμ μν΄ μ μλ κ²½μ°, κ°κ°μ νμ μ μλ₯Ό λ
립μ μΌλ‘ μ¬μ©ν μλ μλ€. μλ₯Ό λ€μ΄ μμ fmap
μ μμμ fmap f Nothing
μ Nothing
μΌλ‘ λ°κΏ μ μμΌλ©°, λ°λλ‘λ κ°λ₯νλ€. μ΄μ μ΄ κ°λ
μ΄ μ€μ λ‘ μ΄λ»κ² μλνλμ§λ₯Ό μ΄ν΄λ³΄μ. λ¨Όμ νλ± λ³΄μ‘΄μ μ΄ν΄λ³΄κ² λ€.
fmap id = id
μ°λ¦¬λ Nothing
κ³Ό Just
λΌλ λ κ°μ§ μΌμ΄μ€λ₯Ό κ³ λ €ν΄μΌνλ€. λ¨Όμ 첫 λ²μ§Έ κ²½μ°λ₯Ό μ΄ν΄λ³΄κ² λ€. μΌμͺ½μ νμ μ€λ₯Έμͺ½ νμΌλ‘ λ³ννκΈ° μν΄ Haskell λ¬Έλ²μ Pseudo Codeλ₯Ό μ¬μ©νκ² λ€.
fmap id Nothing
= { fmapμ μ μμ μνλ©΄ }
Nothing
= { idμ μ μμ μνλ©΄ }
id Nothing
κ°μ₯ λ§μ§λ§ λ¨κ³μμλ id
μ μ μλ₯Ό νμ©νμ¬ ννμ Nothing
μ id Nothing
μΌλ‘ λ체νλ€. μ€μ λ‘λ μ λμμ μ΄λΆμ νμ°λ λ°©μκ³Ό μ μ¬νκ² μ΄λ¬ν μ¦λͺ
μ μνν΄λκ°λ©°, μ€κ°μμ λμΌν ννμμ λ§λ λκΉμ§ μ§ννκ² λλ€. μ μΌμ΄μ€μμλ μΈ λ²μ§Έ λΌμΈμ Nothing
μ΄ μ΄μ ν΄λΉνλ€.
λ λ²μ§Έ κ²½μ°λ μ΄λ ΅μ§ μλ€.
fmap id (Just x)
= { fmapμ μ μμ μνλ©΄ }
Just (id x)
= { idμ μ μμ μνλ©΄ }
Just x
= { idμ μ μμ μνλ©΄ }
id (Just x)
μ΄μ νλ± λ³΄μ‘΄μ λν μ¦λͺ
μ΄ λλ¬μΌλ, fmap
μ΄ ν©μ±μ 보쑴νλ€λ κ²λ ννν΄λ³΄μ.
fmap (g . f) = fmap g . fmap f
첫 λ²μ§Έ Nothing
μ μΌμ΄μ€μ΄λ€.
fmap (g . f) Nothing
= { fmapμ μ μμ μνλ©΄ }
Nothing
= { fmapμ μ μμ μνλ©΄ }
fmap g Nothing
= { fmapμ μ μμ μνλ©΄ }
fmap g (fmap f Nothing)
κ·Έλ¦¬κ³ λ λ²μ§Έ μΌμ΄μ€μΈ Just
μ λν΄μλ μ΄λ κ² νννλ€.
fmap (g . f) (Just x)
= { fmapμ μ μμ μνλ©΄ }
Just ((g . f) x)
= { ν©μ±μ κ²°ν©λ²μΉμ μνλ©΄ }
Just (g (f x))
= { fmapμ μ μμ μνλ©΄ }
fmap g (Just (f x))
= { fmapμ μ μμ μνλ©΄ }
fmap g (fmap f (Just x))
= { ν©μ±μ κ²°ν©λ²μΉμ μνλ©΄ }
(fmap g . fmap f) (Just x)
π‘ μμ£Ό
μ΄λ¬ν μΆλ‘ λ°©μμ΄ μ‘°κΈ μ΄μνκ² λκ»΄μ§λ λ μ λΆλ€λ κ³μ€ν λ°, μ¬μ€ μ μμμ μμ±λ λͺ¨λ μ½λλ€μ λͺ¨λ κ°μ λμμ νλ μ½λμ΄λ€.
λ°©μ μ μΆλ‘ μ΄λΌλ λ§μ΄ μ΄λ €μ보μ¬μ κ·Έλ μ§ κ²°κ΅μ
x
,x + 0
μ΄ λν(Isomorphic)μμ λ°νλκ°λ λ Έκ°λ€μ μ μ¬νλ€.const addZero = (x: number) => x + 0; const identify = <T>(v: T) => v;
identify(addZero(x)); = { identifyμ μ μμ μνλ©΄ } addZero(x) = { addZeroμ μ μμ μνλ©΄ } x = { identifyμ μ μμ μνλ©΄ } identify(x)
ν¨μκ° μ°Έμ‘° ν¬λͺ μ±μ 보μ₯νλ μ΄μ ν¨μλ₯Ό ν¨μμ λ³Έλ¬ΈμΌλ‘ μΉνμ΄ κ°λ₯νκΈ° λλ¬Έμ μ΄λ κ² λ Έκ°λ€λ‘ μ ν©μ±μ νμΈν΄λκ°λ νμκ° κ°λ₯ν κ²μ΄λ€.
μ΄μ κ°μ λ°©μ μ μΆλ‘ μ μ¬μ©ν λλ μ΄ μΆλ‘ λ°©λ²μ΄ μ¬μ΄λ μ΄ννΈλ₯Ό κ°μ§ C++ μ€νμΌμ ν¨μμ λν΄μλ λμνμ§ μλλ€λ μ μ μ μμμΌ νλ€. μλ μ½λλ₯Ό μ΄ν΄λ³΄μ.
int square(int x) {
return x * x;
}
int counter() {
static int c = 0;
return c++;
}
double y = square(counter());
λ°©μ μ μΆλ‘ μ μ¬μ©νλ©΄ square
λ₯Ό μΈλΌμΈννμ¬ μλμ κ°μ μ μλ₯Ό μ»μ μ μλ€.
double y = counter() * counter();
μ΄λ νμ€ν μ ν¨ν λ³νμ΄ μλλ©° λ§€λ² λμΌν κ²°κ³Όλ₯Ό μμ±νμ§λ μμ κ²μ΄λ€. κ·ΈλΌμλ λΆκ΅¬νκ³ λ§€ν¬λ‘λ₯Ό ν΅ν΄ square
λ₯Ό ꡬνν κ²½μ° C++ μ»΄νμΌλ¬λ λ°©μ μ μΆλ‘ μ μλν κ²μ΄κ³ , κ·Έ κ²°κ³Όλ μ°ΈνΉν κ²μ΄λ€.
7.1.3 Optional
λ¬Όλ‘ Haskellμ μ¬μ©νμ¬ νν°λ₯Ό μ½κ² μ μν μ μκΈ°λ νμ§λ§, μ¬μ€ κΌ Haskellμ΄ μλλλΌλ μ λ€λ¦ νλ‘κ·Έλλ°κ³Ό κ³ μ°¨ν¨μλ₯Ό μ§μνλ μ΄λ€ μΈμ΄λ νν°λ₯Ό μ μν μ μλ€. C++μ Maybeμ ν΄λΉνλ ν
νλ¦Ώ νμ
optional
μ μκ°ν΄λ³΄μ. μλλ optional
ꡬνμ λν μ€μΌμΉμ΄λ€. (μ€μ ꡬνμ μΈμκ° μ λ¬λ μ μλ μ¬λ¬κ°μ§ λ°©λ², Deep Copy/Shallow Copyμ κ°μ Copy Semantics, C++ νΉμ μ μμ κ΄λ¦¬ λ¬Έμ λ± μ κ³ λ €ν΄μΌνκΈ° λλ¬Έμ ν¨μ¬ λ 볡μ‘νλ€.)
template<class T>
class optional {
bool _isValid; // the tag
T _v;
public:
optional() : _isValid(false) {} // Nothing
optional(T x) : _isValid(true) , _v(x) {} // Just
bool isValid() const { return _isValid; }
T val() const { return _v; } };
μ΄ ν
νλ¦Ώμ νμ
T
λ₯Ό μλ‘μ΄ νμ
optional<T>
λ‘ λ§€ννμ¬ νν°μ μ μ μ€ νλμΈ νμ
μ λν 맀νμ μ 곡νλ€. μ΄μ ν¨μμ λν λμμ μ μν΄λ³΄μ.
template<class A, class B>
std::function<optional<B>(optional<A>)>
fmap(std::function<B(A)> f) {
return [f](optional<A> opt) {
if (!opt.isValid())
return optional<B>{};
else
return optional<B>{ f(opt.val()) };
};
}
μ΄κ²μ ν¨μλ₯Ό μΈμλ‘ λ°κ³ λ€μ ν¨μλ₯Ό λ°ννλ κ³ μ°¨ν¨μμ΄λ€. 컀λ§λμ§ μλ λ²μ μ λ€μκ³Ό κ°λ€.
template<class A, class B>
optional<B> fmap(std::function<B(A)> f, optional<A> opt) {
if (!opt.isValid())
return optional<B>{};
else
return optional<B>{ f(opt.val()) };
}
μ΄μΈμ fmap
μ optional
μ ν
νλ¦Ώ λ©μλλ‘ λ§λλ μ νμ§λ μλ€. μ΄μ²λΌ λ€μν μ νμ§λ€μ C++μμ νν° ν¨ν΄μ μΆμννλ λμ΄λλ₯Ό λ λνλ μ£Όλ²μ΄λ€. νν°λ₯Ό μμν μ μλ μΈν°νμ΄μ€λ‘ μ μν΄μΌν κΉ? νν°λ 컀λ§λ ν¨μμΈκ° μλλ©΄ 컀λ§λμ§ μμ ν리 ν
νλ¦Ώ ν¨μμΈκ°? C++ μ»΄νΌμΌλ¬λ λλ½λ νμ
μ μ¬λ°λ₯΄κ² μΆλ‘ ν μ μμκΉ, μλλ©΄ μ°λ¦¬κ° μ§μ λͺ
μμ μΌλ‘ μ§μ ν΄μ€μΌ νλκ±ΈκΉ?
νλ² μ
λ ₯ ν¨μ f
κ° int
λ₯Ό λ°μ bool
μ λ°ννλ€κ³ μκ°ν΄λ³΄μ. μ΄ κ²½μ°μ μ»΄νμΌλ¬λ g
μ νμ
μ μ΄λ»κ² κ²°μ ν κΉ?
auto g = fmap(f);
νΉν fmap
μ μ€λ²λ‘λ©νλ μ¬λ¬ κ°μ§ νν°κ° μλ κ²½μ°μλ μ΄λ»κ² λ κΉ? (곧 μ°λ¦¬λ λ λ§μ νν°λ€μ λ§λκ² λ κ²μ΄λ€)
7.1.4 νμ ν΄λμ€(Typeclasses)
κ·Έλ λ€λ©΄ Haskellμ΄ νν°λ₯Ό μΆμννλ λ°©λ²μ 무μμΌκΉ? μ΄λ₯Ό μν΄μ Haskellμ νμ ν΄λμ€ λ§€μ»€λμ¦μ μ¬μ©νλ€. νμ ν΄λμ€λ κ³΅ν΅ μΈν°νμ΄μ€λ₯Ό μ§μνλ νμ μ μ§ν©μ μ μνλ€. μλ₯Ό λ€μ΄, λλ±μ±μ μ§μνλ κ°μ²΄λ€μ ν΄λμ€λ μλμ κ°μ΄ μ μλλ€.
class Eq a where
(==) :: a -> a -> Bool
μ΄ μ μλ νμ
a
κ° Eq
ν΄λμ€μ λ©€λ²μΈ κ²½μ°, νμ
a
κ° λ μΈμλ₯Ό λ°μ Bool
μ λ°ννλ ==
μ°μ°μλ₯Ό μ§μνλ€λ κ²μ λνλΈλ€.
λ§μ½ Haskellμκ² νΉμ νμ
μ΄ Eq
νμ
ν΄λμ€μ μΈμ€ν΄μ€λΌλ κ²μ μλ €μ£Όκ³ μΆλ€λ©΄, λ¨Όμ μ΄ ν΄λμ€μ μΈμ€ν΄μ€λ‘ μ μΈνκ³ ==
μ ꡬνμ μ 곡ν΄μ€μΌ νλ€. μλ₯Ό λ€μ΄ λ κ°μ Float
λ‘ μ΄λ£¨μ΄μ§ κ³± νμ
μΈ 2D Point νμ
μ μ μκ° μ£Όμ΄μ‘λ€κ³ μκ°ν΄λ³΄μ.
data Point = Pt Float Float
μ°λ¦¬λ κ° μ μ λλ±μ±μ μ΄λ κ² μ μν΄λ³Ό μ μλ€.
instance Eq Point where
(Pt x y) == (Pt x' y') = x == x' && y == y'
μ¬κΈ°μλ λ κ°μ ν¨ν΄ (Pt x y)
μ (Pt xβ yβ)
μκ² μ€μ μ°μ°μ ==
λ₯Ό μ¬μ©ν΄λ³΄μλ€. ν¨μμ λ³Έλ¬Έμ λ¨μΌ λ±νΈλ₯Ό 보면 μ΄ν΄κ° μ½λ€. μ΄μ²λΌ Point
κ° Eq
μ μΈμ€ν΄μ€λ‘ μ μΈλλ€λ©΄ μ΄μ μ§μ μ μΌλ‘ μ°μ°μλ₯Ό ν΅ν΄ κ° μ μ λλ±μ±μ λΉκ΅ν μ μλ€.
Haskellμμλ C++μ΄λ Javaμλ λ€λ₯΄κ² Point
λ₯Ό μ μν λ, μ΄ νμ
μ΄ μ§μ Eq
ν΄λμ€μ λ©€λ²λΌλ κ²μ λͺ
μν νμλ μμΌλ©°, μ΄λ μΆν μ¬μ©μκ° μ§μ μμ±νλ ν΄λΌμ΄μΈνΈ μ½λμμ μμ±ν μ μλ€. μ΄λ¬ν νμ
ν΄λμ€λ Haskellμμ ν¨μλ μ°μ°μλ₯Ό μ€λ²λ‘λ©ν μ μλ μ μΌν λ°©λ²μ΄λ€.
λ€μν νν°λ€μμ fmapμ λμμ μ€λ²λ‘λ©νμ¬ νμ©νκΈ° μν΄μλ μ΄μ κ°μ νμ
ν΄λμ€ κΈ°λ²μ΄ νμνλ€. κ·Έλ¬λ ν κ°μ§ 볡μ‘ν μ μ΄ μλ€. νν°λ νμ
μΌλ‘ μ μλλ κ²μ΄ μλλΌ νμ
λ€μ 맀νμΈ νμ
μμ±μλ‘ μ μλλ€. μ¦, νν°λ₯Ό μ λλ‘ μ μνκΈ° μν΄μλ Eq
μ κ²½μ°μ²λΌ νμ
λ€μ μ§ν©μ΄ μλ νμ
μμ±μλ€μ μ§ν©μΌλ‘ μ μλ νμ
ν΄λμ€κ° νμνλ€λ κ²μ΄λ€. λ€ννλ Haskellμ νμ
ν΄λμ€λ νμ
λΏλ§ μλλΌ νμ
μμ±μ λν μ μ§μν΄μ€λ€. κ·ΈλΌ μ΄μ Functor
ν΄λμ€λ₯Ό νλ² μ μν΄λ³΄μ.
class Functor f where
fmap :: (a -> b) -> f a -> f b
μ΄ μ½λλ f
κ° Functor
μΈ κ²½μ°, μ§μ λ νμ
μκ·Έλμ²λ₯Ό κ°μ§ ν¨μ fmap
μ κ°μ§κ³ μλ€λ μ¬μ€μ λͺ
μνκ³ μλ€. μ¬κΈ°μ μλ¬Έμ f
λ νμ
λ³μμ΄λ©°, νμ
λ³μ fmap
μ΄ λ°κ³ μλ a
λ b
μ λμΌν κ°λ
μ΄λ€.
μ»΄νμΌλ¬λ f a
λ f b
μ κ°μ΄ μ΄ νμ
λ³μκ° λ€λ₯Έ νμ
μ μ²λ¦¬νκ³ μλ€λ μ¬μ€μ μ°Έκ³ νμ¬ f
κ° νμ
μ΄ μλ νμ
μμ±μλΌλ μ¬μ€μ μΆλ‘ ν μ μλ€. λ°λΌμ Functor
μ μΈμ€ν΄μ€λ₯Ό μ μΈν λλ Maybe
μ κ°μ νμ
μμ±μλ₯Ό μ§μ ν΄μ€μΌ νλ€.
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just x) = Just (f x)
μ¬μ€ μ°λ¦¬κ° μ μν Functor
ν΄λμ€, κ·Έλ¦¬κ³ Maybe
μ κ°μ΄ κ°λ¨ν λ°μ΄ν° νμ
μ λν μΈμ€ν΄μ€ μ μλ€μ μ΄λ―Έ νμ€ Preludeμ ν¬ν¨λμ΄μλ€.
7.1.5 C++μμμ νν°(Functor in C++)
κ·Έλ λ€λ©΄ C++μμλ μ΄μ λμΌν μ κ·Ό λ°©μμ μλν΄λ³Ό μ μμκΉ? νμ
μμ±μλ optional
κ³Ό κ°μ ν
νλ¦Ώ ν΄λμ€μ ν΄λΉνλ―λ‘, fmap
μ ν
νλ¦Ώ ν
νλ¦Ώ 맀κ°λ³μ F
λ‘ λ§€κ°νν΄λ³Ό μ μμ κ²μ΄λ€.
template<template<class> F, class A, class B>
F<B> fmap(std::function<B(A)>, F<A>);
μ΄μ μ΄ ν νλ¦Ώμ λ€λ₯Έ νν°λ€μ λν΄μ νΉμν(Specialize)νλ©΄ μ’μ κ² κ°λ€. νμ§λ§ μ¬νκ²λ C++μμλ ν νλ¦Ώ ν¨μμ λΆλΆ νΉμνλ₯Ό κΈμ§νκ³ μκΈ° λλ¬Έμ μλμ²λΌ μμ±ν μκ° μλ€.
template<class A, class B>
optional<B> fmap<optional>(std::function<B(A)> f, optional<A> opt)
λμ μ°λ¦¬λ ν¨μ μ€λ²λ‘λ©μ μ¬μ©ν κ²μ΄λ€. μ΄λ κ² λλ©΄ μ°λ¦¬λ λ€μ 컀λ§λμ§ μμ νν°μ μλ μ μλ‘ λμκ°κ² λλ€.
template<class A, class B>
optional<B> fmap(std::function<B(A)> f, optional<A> opt) {
if (!opt.isValid())
return optional<B>{};
else
return optional<B>{ f(opt.val()) };
}
μ΄μ fmap
μ λ λ²μ§Έ μΈμκ° μ€λ²λ‘λλ₯Ό μ ννκΈ° λλ¬Έμ μ΄ μ μ μμ²΄κ° μλνκΈ°λ νμ§λ§, μ΄λ¬ν λ°©λ²μ fmap
μ μΌλ°μ μΈ μ μμμλ λ§μ΄ λ²μ΄λμλ€.
7.1.6 List νν°
νλ‘κ·Έλλ°μμ νν°κ° μ΄λ€ μν μ νλμ§μ λν΄ κ°μ μ‘κΈ° μν΄μλ μ‘°κΈ λ λ§μ μμ λ₯Ό μ΄ν΄λ΄μΌν κ² κ°λ€. λ€λ₯Έ νμ
μΌλ‘ 맀κ°νλ μ΄λ€ νμ
μ΄λ λͺ¨λ νν°μ ν보λΌκ³ λ³Ό μ μλ€. μ λ€λ¦ 컨ν
λμ΄λ μ μ₯λ μμμ νμ
μ μν΄ λ§€κ°νλλ―λ‘, λ§€μ° κ°λ¨ν 컨ν
μ΄λμΈ List
λ₯Ό νλ² μ΄ν΄λ³΄μ.
π‘ μμ£Ό
μ λ€λ¦ 컨ν μ΄λλ μ¬λ¬ νμ μ λ°μ΄ν°λ₯Ό μ μ₯ν μ μλ λ°μ΄ν° 컨ν μ΄λμ΄λ€. μ¦, νμ νλΌλ―Έν°λ₯Ό λ°μμΌλ‘μ¨ λμΌν ꡬ쑰λ₯Ό μ μ§νλ©΄μλ μλ‘ λ€λ₯Έ μ νμ λ°μ΄ν°λ₯Ό μ μ₯ν μ μλ κ²μ΄λ€. TypeScriptμμλ
Array<T>
μ κ°μ νμ μ΄ μΌμ’ μ μ λ€λ¦ 컨ν μ΄λλΌκ³ λ³Ό μ μλ€.
data List a = Nil | Cons a (List a)
μ¬κΈ° List
λΌλ νμ
μμ±μκ° μλ€. μ΄ νμ
μμ±μλ μμμ νμ
a
λ₯Ό νμ
List a
λ‘ λ§€ννλ€. μ΄λ List
κ° νν°λΌλ κ²μ 보μ΄κΈ° μν΄μλ ν¨μ a β b
κ° μ£Όμ΄μ‘μ λ ν¨μ List a β List b
λ‘ λμκ°λ 리νν
ν¨μλ₯Ό μ μν΄μΌ νλ€.
fmap :: (a -> b) -> (List a -> List b)
List a
μ μμ©νλ ν¨μλ λ 리μ€νΈ μμ±μμΈ Nil
κ³Ό Cons
λ κ°μ§ κ²½μ°λ₯Ό κ³ λ €ν΄μΌνλ€. Nil
μ κ²½μ°μλ μ΄μ°¨νΌ λΉ λ¦¬μ€νΈμ λν΄μ ν μ μλκ² μμΌλ, κ·Έλ₯ Nil
μ λ°νν΄μ£Όλ©΄ λλ―λ‘ κ°λ¨νκ² μ²λ¦¬κ° κ°λ₯νλ€.
κ·Έλ¬λ Cons
μΌμ΄μ€μ κ²½μ°μλ μ½κ° κΉλ€λ‘λ€. μλνλ©΄ μ¬κ·λ₯Ό ν¬ν¨ν΄μΌνκΈ° λλ¬Έμ΄λ€. μΌλ¨ μ μ μκ°μ λ©μΆκ³ μ°λ¦¬κ° μ νν μ΄λ€ κ²μ νλ €κ³ νλ κ²μΈμ§ λ€μ μ΄ν΄λ³΄μ. fmap
μ μΈμλ‘ a
μ 리μ€νΈ, κ·Έλ¦¬κ³ a
λ₯Ό b
λ‘ λ³ννλ ν¨μ f
κ° μ£Όμ΄μ‘κ³ , μ΄μ μ΄κ²λ€μ κ°μ§κ³ b
μ 리μ€νΈλ₯Ό μμ±ν΄μΌνλ€.
리μ€νΈμ κ° μμλ₯Ό a
μμ b
λ‘ λ³ννλ κ²μ λΉμ°νκ²λ f
λ₯Ό μ¬μ©νλ©΄ λλ€. λ€λ§ λΉμ΄μμ§ μμ 리μ€νΈλ νλμ μμκ° μλ Cons
λ‘ ννλλ ν€λ(Head)μ λλ¨Έμ§ κΌ¬λ¦¬(Tail)λ‘ κ΅¬μ±λ ν
λ°, μ΄λ»κ² λͺ¨λ μμμ f
λ₯Ό μ μ©ν΄μΌ νλκ±ΈκΉ?
μ°λ¦¬λ f
λ₯Ό ν€λμ λ¨Όμ μ μ©νκ³ , 리νν
ν(fmap
ν) f
λ₯Ό λλ¨Έμ§ κΌ¬λ¦¬μ μ μ©ν κ²μ΄λ€. μ΄λ 리νν
λ f
λ₯Ό λ λ€μ 리νν
ν f
λ‘ μ μνκ³ μκΈ° λλ¬Έμ μ¬κ·μ μΈ μ μκ° λλ€.
fmap f (Cons x t) = Cons (f x) (fmap f t)
π‘ μμ£Ό
Haksellμ μ΅μνμ§ μμ λ μλ€μ μν΄ μ‘°κΈ λ μ½κΈ° μ¬μ΄ λ³μλͺ μΌλ‘ λ°κΏλ³΄λ©΄ λ€μκ³Ό κ°λ€.
fmap μμμμ μ©ν fn (Cons ν€λμμ λλ¨Έμ§ν μΌ) = Cons (μμμμ μ©ν fn ν€λμμ) (fmap μμμμ μ©ν fn λλ¨Έμ§ν μΌ)
μ΄λ₯Ό TypeScriptλ‘ λ€μ μμ±ν΄λ³΄μλ©΄ λλ΅ μ΄λ° λλμ΄λ€.
// List νν° μΈν°νμ΄μ€ interface List<T> { fmap<U>(fn: (value: T) => U): List<U>; } class Cons<T> implements List<T> { constructor(public head: T, public tail: List<T>) {} fmap<U>(fn: (value: T) => U): List<U> { // ν€λμ fnλ₯Ό μ μ©ν΄μ Tλ₯Ό Uλ‘ λ³κ²½ // μ΄ν 꼬리(List)κ° κ°μ§ fmapμ νΈμΆνμ¬ κ°μ νμλ₯Ό μ¬κ·μ μΌλ‘ λ°λ³΅νλ€. return new Cons<U>(fn(this.head), this.tail.fmap(fn)); } }
Haksellμ
Cons (f x)
λ(fmap f t)
μ κ°μ ν¨ν΄λ§€μΉμ ν΅ν΄ ν€λμ μ μ©ν λμκ³Ό 꼬리μ μ μ©ν λμμ ꡬλΆνμ§λ§, TypeScriptλ κ·Έλ° ν¨λ¬λ€μμ κ°μ§ μΈμ΄κ° μλκΈ° λλ¬Έμ μ§μ this
λ₯Ό ν΅ν΄ μνλ λμμ νΈμΆνκ³ μλ€.
μ°νμ fmap f
ꡬ문μ μ μνλ €λ 리μ€νΈλ³΄λ€ λ 짧μ 리μ€νΈ, μ¦, 꼬리μ μ μ©λλ€. κ²°κ΅ μ μ λ 짧μ 리μ€νΈλ‘ μ¬κ·νλ€κ° κ²°κ΅ μ΅μ’
μ μΌλ‘λ λΉ λ¦¬μ€νΈμΈ Nil
μ λλ¬νκ² λ κ²μ΄λ€.
μμ μ μνλλ‘ fmap f
κ° Nil
μ μ μ©λλ©΄ μ¬κ·κ° μ’
λ£λλ€. μ΅μ’
κ²°κ³Όλ₯Ό μ»μΌλ €λ©΄ μλ‘μ΄ ν€λ (f x)
μ μλ‘μ΄ κΌ¬λ¦¬ (fmap f t)
λ₯Ό Cons
μμ±μλ₯Ό ν΅ν΄ κ²°ν©νλ€. μ§κΈκΉμ§ μ΄μΌκΈ°ν λͺ¨λ λ΄μ©μ νλλ‘ ν©μ³λ³΄λ©΄ μλμ κ°μ΄ List νν°μ μΈμ€ν΄μ€ μ μΈμ΄ λλ€.
instance Functor List where
fmap _ Nil = Nil
fmap f (Cons x t) = Cons (f x) (fmap f t)
λ§μ½ μ¬λ¬λΆμ΄ C++μ μ΅μνλ€λ©΄, μΌλ°μ μΈ C++ 컨ν
μ΄λμΈ std::vector
λ₯Ό νλ² μκ°ν΄λ³΄λ©΄ λλ€. std::vector
μ λν fmap
μ ꡬνμ λ¨μν std::transform
μ μμ μΊ‘μνμ λΆκ³Όνλ€.
template<class A, class B>
std::vector<B> fmap(std::function<B(A)> f, std::vector<A> v) {
std::vector<B> w;
std::transform( std::begin(v)
, std::end(v)
, std::back_inserter(w)
, f);
return w;
}
μ΄λ₯Ό μ¬μ©νλ©΄ μ«μ μνμ€μΈ μμλ₯Ό μ κ³±νλ λ±μ νμκ° κ°λ₯νλ€.
std::vector<int> v{ 1, 2, 3, 4 };
auto w = fmap([](int i) { return i*i; }, v);
std::copy( std::begin(w)
, std::end(w)
, std::ostream_iterator(std::cout, ", "));
λλΆλΆμ C++ 컨ν
μ΄λλ std::transform
μ μ λ¬ν μ μλ μ΄ν°λ μ΄ν°λ₯Ό ꡬνν¨μΌλ‘μ¨ νν°κ° λλ©°, μ΄λ fmap
μ μμμ μΈ λ²μ κ³Όλ κ°λ€. κ·Έλ¬λ μνκΉκ²λ μ΄ν°λ μ΄ν°μ μμ κ°μ²΄(Temporaries)μ νΌλμ€λ¬μμΌλ‘ μΈν΄ νν°μ λ¨μν¨μ΄ μλΉ λΆλΆ μ¬λΌμ Έλ²λ¦°λ€(μμ fmap
ꡬνμ μ°Έμ‘°ν΄λ³΄μ). νμ§λ§ μλ‘κ² μ μλ range λΌμ΄λΈλ¬λ¦¬λ νΉμ ν λ²μ λ΄μμ νν°μ μΈ μ±μ§μ λ λͺ
ννκ² ννν΄μ£Όκ³ μλ€.
7.1.7 Reader νν°
μ¬κΈ°κΉμ§ λ΄€λ€λ©΄ μ΄μ νν°κ° μ΄λ€ 컨ν
μ΄λμ ν μ’
λ₯μΈ κ² κ°λ€λ μκ°μ κ°μ§κ² λμμ κ²μ΄λΌ μκ°νλ€. κ·Έλ λ€λ©΄ μ΄μ λ κ·Έ μκ°μ κΉ¨λ²λ¦¬κΈ° μν΄ μ§κΈκΉμ§μ λ§€μ° λ€λ₯Έ κ²μ²λΌ 보μ΄λ μμ λ₯Ό 보μ¬μ£Όλ €κ³ νλ€. νμ
a
λ₯Ό a
λ₯Ό λ°ννλ ν¨μλ‘ λ§€ννλ μν©μ μκ°ν΄λ³΄μ.
μμ§ ν¨μ νμ
μ λν κΉμ΄ μλ μ΄μΌκΈ°λ₯Ό λλμ§λ μμμ§λ§, μ¬μ€ νλ‘κ·Έλλ¨ΈλΌλ©΄ ν¨μμ λν κΈ°λ³Έμ μΈ μ΄ν΄ μ λλ κ°μ§κ³ μλ€. Haskellμμ ν¨μ νμ
μ λ κ°μ νμ
κ³Ό νμ΄ν νμ
μμ±μ(->
)λ₯Ό μ¬μ©νμ¬ κ΅¬μ±λλ€. μ΄ μμ±μλ μΈμ νμ
, κ·Έλ¦¬κ³ κ²°κ³Ό νμ
μ΄λΌλ λ κ°μ§ νμ
μ¬μ΄μ μ€μ ννμΌλ‘ λ±μ₯νλ€. κΈ°λ³Έμ μΌλ‘λ a -> b
μ ννμ΄μ§λ§ κ΄νΈλ₯Ό μ¬μ©νλ©΄ μ μ ννμΌλ‘λ μ¬μ©μ΄ κ°λ₯νλ€.
(->) a b
μ κ· ν¨μμ λ§μ°¬κ°μ§λ‘ νλ μ΄μμ μΈμλ₯Ό κ°μ§ νμ ν¨μλ λΆλΆμ μ©μ΄ κ°λ₯νλ€. λ°λΌμ μλ μμμ κ°μ΄ νμ΄νμ νλμ νμ μΈμλ§ μ 곡νλ€λ©΄ κ²°κ³Ό νμ μ μλ―Ένλ λ€λ₯Έ μΈμκ° λ€μ΄μ€λ κ²μ κΈ°λ€λ¦΄ μ μλ€λ κ²μ΄λ€.
(->) a
μ΄κ²μ΄ λ°λ‘ μ ννμ΄ νμ
μμ±μμΈ μ΄μ μ΄λ€. a -> b
λ₯Ό μμ ν νμ
μΌλ‘ λ§λ€κΈ° μν΄μλ νμ
b
κΉμ§ μ 곡λμ΄μΌ νκΈ° λλ¬Έμ΄λ€. μ¦, μ μμλ νμ
a
λ₯Ό 맀κ°λ³μλ‘ μ¬μ©νλ νμ
μμ±μ μ§ν©μ μ μνκ³ μλ€κ³ λ³Ό μ μλ€.
κ·Έλ λ€λ©΄ μ΄μ μ΄ μΌμ΄μ€κ° νν°κ° λ§λμ§ μ΄ν΄λ³΄λλ‘ νμ. λ κ°μ νμ
맀κ°λ³μλ₯Ό λ€λ£¨λ κ²μ μ΄λ €μΈ μ μμΌλ μ΄λ¦μ μ‘°κΈ λ³κ²½ν΄λ³΄κ² λ€. μ΄μ μ μ μνλ νν°μ μ μμ μΌμΉνλλ‘ μΈμμ νμ
μ r
λ‘, κ²°κ³Ό νμ
μ a
λ‘ μ§μ ν΄λ³΄κ² λ€.
μ¦, μ΄ νμ
μμ±μλ μμμ νμ
a
λ₯Ό r -> a
νμ
μΌλ‘ 맀ννλ λ
μμ΄λ€. μ΄κ²μ΄ νν°κ° λλ €λ©΄ ν¨μ a -> b
, ν¨μ r -> a
λ₯Ό μΈμλ‘ λ°κ³ ν¨μ r -> b
λ₯Ό λ°ννλ ν¨μλ‘ λ¦¬νν
ν΄μΌ νλ€. μ΄λ€μ κ°κ° νμ
μμ±μ(->
) r
μ΄ μμ©νλ νμ
a
μ b
λ₯Ό μ¬μ©νμ¬ νμ±λ νμ
μ΄λ€.
μ΄μ μ΄ μΌμ΄μ€λ₯Ό ννν μ μλ fmap
μ μ μλ₯Ό μ΄ν΄λ³΄μ.
fmap :: (a -> b) -> (r -> a) -> (r -> b)
μ°λ¦¬λ ν¨μ f::a -> b
μ ν¨μ g::r -> a
κ° μ£Όμ΄μ‘μ λ ν¨μ r -> b
λ₯Ό μμ±ν΄μΌνλ νΌμ¦μ νμ΄μΌ νλ€. λ ν¨μλ₯Ό ν©μ±ν μ μλ λ°©λ²μ μ€μ§ νλ λΏμ΄λ©°, κ²°κ³Ό λν μ°λ¦¬κ° μνλ λ°©ν₯κ³Ό μ νν μΌμΉνλ€. λ°λΌμ fmap
μ ꡬνμ μλμ κ°μ κ²μ΄λ€.
instance Functor ((->) r) where
fmap f g = f . g
π‘ μμ£Ό
g::r β a
,f::a β b
κ° ν©μ±λ¨μΌλ‘μ¨r β a β b
, μ¦r β b
κ° μ±λ¦½λλ€.
κ΅μ₯ν κ°κ²°νμ§λ§ μ°λ¦¬κ° μνλ λμμ μ νν ꡬνλμλ€. λ§μ½ λ κ°κ²°ν νκΈ°λ₯Ό μ νΈνλ€λ©΄, ν¨μ ν©μ±μ λν ννμ μ μ νκΈ°λ²μΌλ‘ λ°κΏλ³Ό μλ μλ€.
fmap f g = (.) f g
κ·Έλ¦¬κ³ μΈμλ₯Ό μλ΅ν΄μ fmap
κ³Ό ν¨μ ν©μ±μ μλ―Ένλ .
μ°μ°μ, λ ν¨μμ μ§μ μ μΈ λλ±μ±μ ννν μλ μλ€.
fmap = (.)
μ΄μ²λΌ (->) r
νμ
μμ±μμ fmap
ꡬνμ κ²°ν©μ Reader νν°λΌκ³ νλ€.
7.2 컨ν μ΄λλ‘μ¨μ νν°
μ§κΈκΉμ§ νλ‘κ·Έλλ° μΈμ΄μμ μΌλ°μ μΈ μ©λμ 컨ν μ΄λλ₯Ό μ μνλ νν°μ λͺ κ°μ§ μμλ₯Ό μ΄ν΄λ³΄μλ€.
μ°λ¦¬λ λ³΄ν΅ ν¨μλ₯Ό μΌμ’ μ λ°μ΄ν°λΌκ³ μκ°νμ§μκΈ° λλ¬Έμ Reader νν°κ°μ λ μλ€μ΄ μ‘°κΈ μ΄μν΄λ³΄μ΄κΈ°λ νλ€. κ·Έλ¬λ μμν¨μλ λ©λͺ¨μ΄μ μ΄μ λ μ μμΌλ©° ν¨μμ μ€νμ μΌμ’ μ ν μ΄λΈ μ‘°ν νμλ‘ λ³νλ μλ μλ€. κ·Έλ¦¬κ³ ν μ΄λΈμ λ°μ΄ν°μ΄λ€.
π‘ μμ£Ό
ν¨μμ μ€νμ μΌμ’ μ ν μ΄λΈ μ‘°ν νμλ‘ λ³νν μ μλ€λ λ§μ μ΄λ€ ν¨μκ° μμνκ³ λΆλ³μ μ΄λ©° μ λ ₯μ λ°λΌ νμ κ°μ μΆλ ₯μ λ°ννλ€λ κ°μ μ μ μ λ‘ νλ μ€λͺ μ΄λ€.
μμ κ°μ μ μ κ° μ§μΌμ§λ€λ©΄ ν¨μμ μ€ν κ²°κ³Όλ₯Ό ν μ΄λΈμ μ μ₯νκ³ ν¨μμ μ λ ₯ κ°μ ν€λ‘ μ¬μ©νμ¬ ν¨μμ μ€ν κ²°κ³Όλ₯Ό βκ²μβν μ μλ€.
μ΄λ¬ν λ©λͺ¨μ΄μ μ΄μ μ μ¬μ©λλ μλ£κ΅¬μ‘°κ° κΌ ν μ΄λΈμ΄μ΄μΌλ§ νλ κ²μ μλμ§λ§, μκ°λ μμν ν¨μμ μ΄λ¬ν νΉμ±μΌλ‘ μΈν΄ μμν¨μμ μ€νμ΄ μΌμ’ μ λ°μ΄ν° μ‘°ν νμκ° λ μ μλ€λ μ¬μ€μ κ°μ‘°νκ³ μλ κ²μ΄λ€.
λ°λλ‘ Haskellμ κ²μΌλ₯Έ νκ°(μ§μ°νκ°) λλ¬Έμ μ ν΅μ μΈ μ»¨ν μ΄λμΈ λ¦¬μ€νΈλ ν¨μλ‘ κ΅¬νλ μλ μλ€. μλ₯Ό λ€μ΄ μμ°μμ 무νν 리μ€νΈλ μλμ κ°μ΄ κ°κ²°νκ² μ μν μ μλ€.
nats :: [Integer]
nats = [1..]
첫 λ²μ§Έ λΌμΈμ λκ΄νΈ μμ Haskellμ 리μ€νΈμ λν λ΄μ₯ νμ μμ±μμ΄λ€. λ λ²μ§Έ λΌμΈμ λκ΄νΈλ 리μ€νΈ 리ν°λ΄μ λ§λλ λ° μ¬μ©λλ€.
λΉμ°νκ² μ§λ§ μ΄λ° λ°©μμ 무ν 리μ€νΈλ λ©λͺ¨λ¦¬μ μ μ₯ν μ μλ€. κ·Έλμ νμν λλ§λ€ Integer
λ₯Ό μμ±νλ ν¨μλ‘ μ΄λ¬ν λμμ ꡬννλ κ²μ΄λ€. Haskellμ μ¬μ€μ λ°μ΄ν°μ μ½λ μ¬μ΄μ ꡬλΆμ λͺ
ννκ² νμ§ μλλ€. 리μ€νΈλ ν¨μλ‘ κ°μ£Όλ μλ μκ³ , ν¨μλ μΈμλ₯Ό κ²°κ³Όμ 맀ννλ ν
μ΄λΈλ‘ κ°μ£Όλ μλ μλ€. νΉν νμλ ν¨μμ μ μμμ΄ μ ννκ³ ν¬κΈ°κ° ν¬μ§ μμ κ²½μ°μλ κ½€λ μ€μ©μ μΈ κ°λ
μ΄λ€.
κ·Έλ¬λ strlen
μ ν
μ΄λΈ μ‘°νλ‘ κ΅¬ννλ κ²μ νμ€μ μ΄μ§ μλ€. μλνλ©΄ 무νν λ§μ μλ‘ λ€λ₯Έ λ¬Έμμ΄λ€μ΄ μ‘΄μ¬νκΈ° λλ¬Έμ΄λ€. νλ‘κ·Έλλ¨Έλ‘μ¨ μ°λ¦¬λ 무νμ μ’μνμ§ μκ² μ§λ§, μΉ΄ν
κ³ λ¦¬ μ΄λ‘ μμλ 무νμ μμΉ¨μμ¬μ²λΌ μ¦κΈ°λ λ°©λ²μ λ°°μλ³Ό μ μλ€. λͺ¨λ λ¬Έμμ΄μ μ§ν©μ΄λ μ°μ£Όμ κ³Όκ±°, νμ¬, λ―Έλμ μν κ°μ΄ 무νν κ²λ€λ λ€λ€λ³Ό μ μλ€λ λ§μ΄λ€.
κ·Έλμ νμλ νν° κ°μ²΄(μλνν°μ μν΄ μμ±λ νμ μ κ°μ²΄)λ₯Ό μ΄λ€ νμ μ κ°μ§ κ° λλ κ°λ€μ μΆμμ μΌλ‘ κ°μ§κ³ μλ 무μΈκ°λ‘ μκ°νλ κ²μ μΆμ²νλ€. 물리μ μΌλ‘ κ·Έ κ°μ κ°μ§κ³ μμ§λ μμ§λ§ λ§μ΄λ€.
π‘ μμ£Ό
μ¬κΈ°μ μκ°κ° νν°κ° νΉμ νμ μ κ°μ μ§μ κ°μ§κ³ μλ κ²μ΄ μλλΌ μΆμμ μΌλ‘ κ°μ§κ³ μλ€κ³ νννλ μλ―Έλ λ€μκ³Ό κ°λ€. TypeScriptμ Arrayλ₯Ό μλ‘ λ€μ΄λ³΄μ.
const numbers: number[] = [1, 2, 3]; // μ«μ νμ μ λ°°μ΄ const doubledNumbers = numbers.map(x => x * 2); // [2, 4, 6]
μ¬κΈ°μ
number[]
νμ μ λ°°μ΄μ μ¬μ€ βλͺ¨λ μ«μλ₯Ό κ°μ§ λ°°μ΄βμΌλ‘ μ μλμλ€κ³ λ΄μΌ νλ€. νμ§λ§ νμ¬ μ΄ λ°°μ΄μ΄ μ€μ λ‘ λͺ¨λ μ«μλ₯Ό κ°μ§κ³ μλ κ²μ μλλ©°, λ¨μ§map
κ³Ό κ°μ λ©μλλ₯Ό μ¬μ©νμ¬ λ°°μ΄ λ΄λΆμ κ°λ€μ κ°μ μ μΌλ‘ λ€λ£° μ μλ λ°©λ²λ§μ μ 곡νκ³ μλ€.μ΄λ¬ν λ°©λ²λ€μ ν΅ν΄ μ΄ λ°°μ΄μ μ΄λ‘ μ λͺ¨λ μ«μλ₯Ό κ°μ§ μ μκ² μ§λ§, μ€μ λ‘ μ΄ λ°°μ΄μ΄ λͺ¨λ μ«μλ₯Ό κ°μ§κ³ μλ κ²μ μλκΈ°μ βμΆμμ μΌλ‘ κ°μ§κ³ μλ€βλΌλ ννμ μ¬μ©ν κ²μ΄λ€.
C++μμμ μμλ₯Ό 보μλ©΄ std::future
κ° μλ€. μΈμ κ°λ κ°μ κ°μ§κ² λ ν
μ§λ§ λ°λμ κ·Έλ λ€λ 보μ₯μ μμΌλ©°, Future λ΄λΆμ κ°μ μ κ·Όνλ €λ©΄ λ€λ₯Έ μ€λ λμ μ€νμ΄ μλ£λ λκΉμ§ κΈ°λ€λ €μΌν μλ μλ€.
λ λ€λ₯Έ μμλ‘λ Haskellμ IO
κ°μ²΄κ° μλ€. μ΄ κ°μ²΄λ μ¬μ©μμ μ
λ ₯μ λ°κ±°λ βHello World!βκ° λͺ¨λν°μ νμλ μ°μ£Όμ μνλ₯Ό ν¬ν¨ν μλ μλ€.
μ΄λ¬ν ν΄μλ€μ λ°λ₯΄λ©΄ νν° κ°μ²΄λ 맀κ°λ³μνλ νμ μ κ°μ ν¬ν¨νκ±°λ κ·Έλ° κ°μ μμ±νλ λ°©λ²μ ν¬ν¨νκ³ μλ 무μΈκ°λ‘ λ°λΌλ³Ό μ μλ€. νν° λ΄λΆμ κ°μ μ κ·Όνλ λμμ μμ ν μ νμ¬νμ΄λ©° νν°μ λ²μμ κΌ ν¬ν¨λμ΄μΌ νλ λμλ μλλ€. μ°λ¦¬κ° κ΄μ¬μ κ°μ ΈμΌνλ λΆλΆμ ν¨μλ₯Ό μ¬μ©ν΄μ κ·Έ κ°μ μ‘°μν μ μλ€λ κ² λΏμ΄λ€.
λ§μ½ κ·Έ κ°μ μ κ·Όν μ μλ€λ©΄ κ·Έ μ‘°μμ λν κ²°κ³Όλ₯Ό λ³Ό μ μμ΄μΌ νλ€. κ·Έλ¬λ μ κ·Όν μ μλ€λ©΄ μ°λ¦¬κ° μ€μ§ μ κ²½μ¨μΌνλ κ²μ κ·Έ μ‘°μλ€μ΄ μ¬λ°λ₯΄κ² ν©μ±λμλμ§, κ·Έλ¦¬κ³ νλ± ν¨μλ₯Ό ν΅ν μ‘°μμ μ무κ²λ λ°κΎΈμ§ μλλ€λ μ¬μ€ λΏμ΄λ€. νν° κ°μ²΄ λ΄λΆμ κ°μ μ κ·Όνλ κ²μ΄ κ·Έλ κ² μ€μν μΌμ΄ μλλΌλ κ²μ 보μ¬μ£ΌκΈ° μν΄ ν κ°μ§ μμλ₯Ό 보μ¬μ£Όκ² λ€. μ¬κΈ° μΈμ a
λ₯Ό μμ ν 무μνλ νμ
μμ±μκ° μλ€.
data Const c a = Const c
Const
νμ
μμ±μλ c
μ a
λ κ°μ νμ
μ λ°λλ€. νμ΄ν μμ±μ λμ λ§μ°¬κ°μ§λ‘ μ΄λ₯Ό λΆλΆμ μΌλ‘ μ μ©ν΄μ νν°λ₯Ό λ§λ€μ΄λ³Ό κ²μ΄λ€. Const
λΌκ³ νλ λ°μ΄ν° μμ±μλ c
νμ
μ κ° νλλ§μ μ·¨νλ©°, μ΄λ a
μ λν μμ‘΄μ±μ΄ μλ€λ κ²μ μλ―Ένλ€. μ΄ νμ
μμ±μμ λν fmap
μ νμ
μ μλ μλμ κ°λ€.
fmap :: (a -> b) -> Const c a -> Const c b
νν°κ° νμ
μΈμλ₯Ό 무μνκ³ μκΈ° λλ¬Έμ, fmap
μ ꡬνμμλ ν¨μ μΈμλ₯Ό 무μν μ μλ€. ν¨μμ μ μ©ν λμ μμ²΄κ° μκΈ° λλ¬Έμ΄λ€.
instance Functor (Const c) where
fmap _ (Const v) = Const v
μ€νλ € μ΄λ° λΆλΆμ μ»΄νμΌ μκ°μ λ°μνλ νμ μΈμμ λ°νμμ λ°μνλ κ° μ¬μ΄μ λ κ°ν ꡬλΆμ΄ μλ C++μμ λ λͺ ννκ² λνλ μ μλ€.
template<class C, class A>
struct Const {
Const(C v) : _v(v) {}
C _v;
};
C++μΌλ‘ ꡬνλ fmap
λν ν¨μμ μΈμλ₯Ό 무μνκ³ Const
μΈμλ₯Ό λ³Έλ κ°κ³Ό ν¨κ» λ€μ μΊμ€ν
νλ μν μ μννλ€.
template<class C, class A, class B>
Const<C, B> fmap(std::function<B(A)> f, Const<C, A> c) {
return Const<C, B>{c._v};
}
λΉμ₯ μ΄ν΄νκΈ°λ μ΄λ €μΈ μ μμ§λ§ μ¬μ€ Const
νν°λ λ§μ ꡬ쑰λ€μμ κ΅μ₯ν μ€μν μν μ λ΄λΉνλ€. μΉ΄ν
κ³ λ¦¬ μ΄λ‘ μμ Const
νν°λ μμ μΈκΈνλ λΈλνμ μλνν°, μ¦, νν°μ νΉμν κ²½μ°μ΄λ€. μΆν μ΄λ¬ν κ°λ
μ λν΄μλ λ μμΈν λ€λ€λ³΄λλ‘ νκ² λ€.
7.3 νν° ν©μ±(Functor Composition)
νν°κ° λ§μΉ ν¨μμ κ°μ΄ ν©μ±λ μ μλ€λΌλ κ²μ κ½€ μ§κ΄μ μΈ μ΄ν΄κ° κ°λ₯ν μ¬μ€μ΄λ€. κ²°κ΅ λ νν°μ ν©μ±μ΄λΌλ κ²μ νν°κ° νΉμ μΉ΄ν κ³ λ¦¬ λ΄μ κ°μ²΄λ μ¬μμ 맀νλλ νμλ€μ ν©μ±μ΄λΌκ³ λ³Ό μ μλ€.
ν©μ±λ λ κ°μ νν°λ₯Ό κ±°μΉλλΌλ νλ± μ¬μμ κ·Έλλ‘ νλ± μ¬μμΌλ‘ λ¨κ² λλ©°, μ¬μλ€μ ν©μ± κ·μΉμ μ¬μ ν λμΌν κ·μΉμ κ°μ§κ² λλ€. μ΄λ κ΅μ₯ν λ¨μνκ³ κ°λ¨ν κ·μΉμ΄λ©°, νΉν μλνν°λ₯Ό ν©μ±νλ κ²μ λλμ± μ½λ€. νΉμ maybeTail
ν¨μλ₯Ό κΈ°μ΅νλκ°?
μ΄ ν¨μλ₯Ό Haskellμ λ΄μ₯ 리μ€νΈ ꡬνμ μ¬μ©ν΄μ λ€μ μμ±ν΄λ³΄κ² λ€.
maybeTail :: [a] -> Maybe [a]
maybeTail [] = Nothing
maybeTail (x:xs) = Just xs
μ§κΈκΉμ§ Nil
λ‘ νΈμΆνλ λΉ λ¦¬μ€νΈ μμ±μλ λΉ λκ΄νΈ μμΈ []
μΌλ‘ λ체λμκ³ , Cons
μμ±μλ μ€μ μ°μ°μ :
μΌλ‘ λ체λμλ€.
maybeTail
μ κ²°κ³Όλ λ νν° Maybe
, []
κ° a
μ μμ©νλ ννλ₯Ό μ§λκ³ μλ€. λ§μ½ μ¬κΈ°μ ν©μ±λ Maybe
리μ€νΈμ μμμ μ΄λ€ ν¨μ f
λ₯Ό μ μ©νλ €κ³ νλ€λ©΄ μ΄λ»κ² μ κ·Όν΄μΌν κΉ?
ν¨μκ° Maybe
리μ€νΈμ μμμ λλ¬νκΈ° μν΄μλ Maybe
μ []
λΌλ λ κ²Ήμ νν°λ₯Ό λ«μ΄μΌ νλ€. κ°μ₯ λ¨Όμ μΈλΆμ Maybe
λ₯Ό λ«κΈ° μν΄ fmap
μ μ¬μ©ν μ μλ€. κ·Έλ¬λ ν¨μ f
λ 리μ€νΈμ λν΄μλ μλνμ§ μκΈ° λλ¬Έμ μ΄λλ‘ μ΄ ν¨μλ₯Ό Maybe
μ μμͺ½μΌλ‘ λ³΄λΌ μλ μλ€. μ°λ¦¬λ λ΄λΆ 리μ€νΈμμ μλν (fmap f)
λ₯Ό 보λ΄μΌ νλ€. νλ² Maybe
리μ€νΈμ μ μ μμλ€μ μ κ³±νλ μμλ₯Ό 보λλ‘ νμ.
square x = x * x
mis :: Maybe [Int]
mis = Just [1, 2, 3]
mis2 = fmap (fmap square) mis
λ¨Όμ μ»΄νμΌλ¬λ νμ
μ λΆμν ν, μΈλΆμ fmap
μ λν΄μλ Maybe
μΈμ€ν΄μ€μ ꡬνμ μ¬μ©νκ³ , λ΄λΆμ fmap
μ λν΄μλ 리μ€νΈ νν°μ ꡬνμ μ¬μ©ν΄μΌνλ€λ κ²μ μΆλ‘ ν΄λΌ κ²μ΄λ€. λ¬Όλ‘ μ§κΈ μμ μμ μ μ½λκ° μλμ κ°μ μ½λλ‘ λ€μ μμ±λ μ μλ€λ μ¬μ€μ΄ λ°λ‘ μ΄ν΄κ° λμ§λ μμ μλ μλ€.
mis2 = (fmap . fmap) square mis
κ·Έλ¬λ fmap
μ νλμ μΈμμ λν ν¨μλ‘ κ°μ£Όλ μ μλ€λ κ²μ κΈ°μ΅ν΄μΌνλ€.
fmap :: (a -> b) -> (f a -> f b)
μ΄ κ²½μ° (fmap . fmap)
μμ λ λ²μ§Έ fmap
μ λ€μκ³Ό κ°μ νμ
μ μΈμλ₯Ό μ·¨νλ€.
square :: Int -> Int
κ·Έλ¦¬κ³ λ€μκ³Ό κ°μ νμ μ ν¨μλ₯Ό λ°νν κ²μ΄λ€.
[Int] -> [Int]
μ΄ν 첫 λ²μ§Έ fmap
μ μ΄ ν¨μλ₯Ό μ·¨νκ³ λ€μκ³Ό κ°μ νμ
μ ν¨μλ₯Ό λ°ννλ€.
Maybe [Int] -> Maybe [Int]
κ·Έλ¦¬κ³ λΉλ‘μ μ΄ ν¨μκ° mis
μ μ μ©λλ€. λ°λΌμ λ νν°μ ν©μ±μ ν΄λΉ fmap
λ€μ ν©μ±μΈ νν°λΌκ³ λ³Ό μ μλ€.
λ€μ μΉ΄ν κ³ λ¦¬ μ΄λ‘ μΌλ‘ λμκ°λ³΄μ. λμλ€μ 맀νμ΄ κ²°ν©λ²μΉμ λ§μ‘±νλ©°, μ¬μλ€μ 맀νλ κ²°ν©λ²μΉμ λ§μ‘±νλ νν°μ ν©μ± λν κ²°ν©λ²μΉμ λ§μ‘±νλ€λ μ¬μ€μ λͺ ννλ€. κ·Έλ¦¬κ³ λͺ¨λ μΉ΄ν κ³ λ¦¬μλ λΉμ°ν νλ± νν° λν μ‘΄μ¬νλ€. νλ± νν°λ λͺ¨λ λμκ³Ό μ¬μμ΄ μκΈ°μμ μκ² λ§€νλλ νν°μ΄λ€.
μ¦, νν°λ λ§μΉ μ΄λ ν μΉ΄ν κ³ λ¦¬μ μ¬μλ€κ³Ό λμΌν νΉμ±μ κ°μ§κ² λλ€. κ·Έλ λ€λ©΄ κ·Έ μΉ΄ν κ³ λ¦¬λ 무μμΌκΉ?
λ°λ‘ λμμ΄ μΉ΄ν κ³ λ¦¬μ΄κ³ , μ¬μμ΄ νν°μΈ μΉ΄ν κ³ λ¦¬μ΄λ€. μ¦, μΉ΄ν κ³ λ¦¬λ€μ μΉ΄ν κ³ λ¦¬λΌκ³ ν μ μλ€. κ·Έλ¬λ λͺ¨λ μΉ΄ν κ³ λ¦¬λ€μ μΉ΄ν κ³ λ¦¬ λν μΉ΄ν κ³ λ¦¬μ΄λ, μκΈ° μμ μ μκΈ° μμ μμ ν¬ν¨ν΄μΌνλ λͺ¨μμ λΉ μ§κ² λλ€.
λͺ¨λ βμμβ μΉ΄ν κ³ λ¦¬μ μΉ΄ν κ³ λ¦¬μΈ Catμ΄λΌλ κ°λ μ΄ μλ€. μμ μΉ΄ν κ³ λ¦¬λ λμλ€μ΄ μ§ν©μ νμ±νλ μΉ΄ν κ³ λ¦¬λ₯Ό κ°λ¦¬ν€λ©°, μ¬μ§μ΄ 무ννμ¬ μ μ μλ μ§ν©λ βμμβ μΉ΄ν κ³ λ¦¬λ‘ κ°μ£Όλλ€. νμλ μ΄λ° κ°λ λ€μ΄ λ€μν μΆμν μμ€μμ λμΌν κ΅¬μ‘°κ° λ°λ³΅λλ κ²μ ννν μ μλ€λ κ²μ λ§€μ° λλΌμ λ€. μ¬μ§μ΄ λμ€μλ νν°λ€μ΄ μΉ΄ν κ³ λ¦¬λ₯Ό νμ±νλ μΌμ΄μ€λ λ³΄κ² λ κ²μ΄λ€.
κ΄λ ¨ ν¬μ€ν 보λ¬κ°κΈ°
[λ²μ] νλ‘κ·Έλλ¨Έλ₯Ό μν μΉ΄ν κ³ λ¦¬ μ΄λ‘ - 10. μμ° λ³ν
[λ²μ] νλ‘κ·Έλλ¨Έλ₯Ό μν μΉ΄ν κ³ λ¦¬ μ΄λ‘ - 9. ν¨μ νμ
[λ²μ] νλ‘κ·Έλλ¨Έλ₯Ό μν μΉ΄ν κ³ λ¦¬ μ΄λ‘ - 8. νν°μ νΉμ±
[λ²μ] νλ‘κ·Έλλ¨Έλ₯Ό μν μΉ΄ν κ³ λ¦¬ μ΄λ‘ - 6. λ¨μν λμμ νμ
[λ²μ] νλ‘κ·Έλλ¨Έλ₯Ό μν μΉ΄ν κ³ λ¦¬ μ΄λ‘ - 5. κ³±κ³Ό ν©