# <译> 自然变换

α_a :: F a -> G a

F f :: F a -> F b
G f :: G a -> G b

α_a :: F a -> G a
α_b :: F b -> G b

G f ∘ α_a = α_b ∘ F f

α_b = (G f) ∘ α_a ∘ (F f)^(-1)>

# 多态函数

alpha_a :: F a -> G a

alpha :: forall a . F a -> G a

forall a 在 Haskell 中是可选的（可以用语言扩展 ExplicitForAll 开启它）。通常，可将其写为：

alpha :: F a -> G a

template<Class A> G<A> alpha(F<A>);

alpha :: F a -> G a

G f ∘ α_a = α_b ∘ F f

fmap_G f . alphaa = alphab . fmap_F f

fmap f . alpha = alpha . fmap f

safeHead :: [a] -> Maybe a
safeHead (x:xs) = Just x

fmap f . safeHead = safeHead . fmap f

fmap f (safeHead []) = fmap f Nothing = Nothing

safeHead (fmap f []) = safeHead [] = Nothing

fmap f (safeHead (x:xs)) = fmap f (Just x) = Just (f x)

safeHead (fmap f (x:xs)) = safeHead (f x : fmap f xs) = Just (f x)

fmap f [] = []
fmap f (x:xs) = f x : fmap f xs

fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)

length :: [a] -> Const Int a
length [] = Const 0
length (x:xs) = Const (1 + unConst (length xs))

unConst :: Const c a -> c
unConst (Const x) = x

length :: [a] -> Int

scam :: Const Int a -> Maybe a
scam (Const x) = Nothing

newtype Reader e a = Reader (e -> a)

instance Functor (Reader e) where
fmap f (Reader g) = Reader (\x -> f (g x))

alpha :: Reader () a -> Maybe a

dumb (Reader _) = Nothing

obvious

obvious (Reader g) = Just (g ())

（用 g 能做的事情仅仅是让它作用于 ()。）

# 超自然性

newtype Op r a = Op (a -> r)

instance Contravariant (Op r) where
contramap f (Op g) = Op (g . f)

predToStr (Op f) = Op (\x -> if f x then "T" else "F")

contramap f . predToStr = predToStr . contramap f

contramap :: (b -> a) -> (Op Bool a -> Op Bool b)

a -> a

(a -> a) -> f a

# 函子范畴

α_a :: F a -> G a

β_a :: G a -> H a

β_a ∘ α_a :: F a -> H a

(β ⋅ α)_a = β_a ∘ α_a

H f ∘ (β ⋅ α)_a = (β ⋅ α)_b ∘ F f

id_{F a} :: F a -> F a

# 2-范畴

Cat 的 2-范畴具有：

• 对象：（小）范畴
• 1-态射：范畴之间的函子
• 2-态射：函子之间的自然变换

F :: C -> D
G :: D -> E

G ∘ F :: C -> E

α :: F -> F'
β :: G -> G'

α_a :: F a -> F'a

G (F a), G'(F a), G (F'a), G'(F'a)

β_{F a} :: G (F a) -> G'(F a)
β_{F'a} :: G (F'a) -> G'(F'a)

G α_a :: G (F a) -> G (F'a)
G'α_a :: G'(F a) -> G'(F'a)

G (F a)G'(F'a) 的路径不是一条，而是两条：

G'α_a ∘ β_{F a}
β_{F'a} ∘ G α_a

β ∘ α :: G ∘ F -> G'∘ F'

(β' ⋅ α') ∘ (β ⋅ α) = (β' ∘ β) ⋅ (α' ∘ α)

F ∘ α

α ∘ F

α 位于 1_F 之后的横向复合。

# 挑战

1. 定义从 Maybe 到列表函子的自然变换，并证明它符合自然性条件。
2. Reader () 与列表函子构造至少两个不同的自然变换。存在多少个不同的 () 列表？
3. Reader BoolMaybe 来做上一个练习。
4. 揭示自然变换的横向复合满足自然性条件（提示：使用分量）。对于追求示意图的人而言，这是个很好的练习。
5. 写一篇文章，谈谈你是如何觉得画显而易见的示意图胜过证明交换律。
6. 为不同的 Op 函子之间的变换的相反自然性条件，创建一些测试案例。以下是一个示例：
op :: Op Bool Int
op = Op (\x -> x > 0)

f :: String -> Int
f x = read x

# 致谢

$$\cdot$$

2 条评论
Yumenokanata · 2017年12月12日

dreday · 4月29日