一、 Monad(单子)定义
1. 范畴论中的定义
Monad可以定义在2-范畴中,在此我们以范畴Cat为例:
Monad可以表示为一个四元组
(C,M:C→C,Unit:1C→M,Join:M∘M→M)
其中
C
是范畴,
- Join∘MUnit=Join∘UnitM=IdM
- Join∘JoinM=Join∘MJoin
2. Haskell中的定义
在函数式编程语言Haskell中,monad首先是一个函子 M:Hask→Hask ,其次满足如下四条性质:
1. unit x >>= f <=> f x
2. x >>= unit <=>x
3. (m >>= f) >>= g <=> m >>= ((>>= g) . f)
4. fmap f x <=> x >>= (unit . f) (fmap在monad中的定义)
其中, unit <=> return <=> pure
fmap 在该定义下是函子:
fmap id = (>>= unit .id) = id
(保持单位态射)
fmap (g . f) = (>>= unit . g . f)
= (>>= (>>= unit . g) . unit . f)
= (>>= unit . g) . (>>= unit . f)
= fmap g . fmap f
(保持结合律)
3.二者定义的等价性
为方便证明,现分别列出小节1. 和 2.中的定义等价形式,并改写成Haskell语言的形式。
范畴论中的定义
- JoinX∘M(JoinX)≡JoinX∘JoinM(X) (交换图)
- JoinX∘M(UnitX)≡JoinX∘UnitM(X) (交换图)
- Unitcod(f)∘f≡M(f)∘Unitdom(f) (自然变换)
- Joincod(f)∘M2(f)≡M(f)∘Joindom(f) (自然变换)
改写后形式如下:
1. join . fmap join <=> join . join
2. join . fmap unit <=> join . unit = id
3. unit . f <=> fmap f . unit
4. join . fmap (fmap f) <=> fmap f . join
5. (>>= f) <=> join . fmap f
其中,式5. 利用函数join定义函数(>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
x >>= f = join . fmap f $ x
Haskell中的定义
改写成pointfree风格:
1. (>>= f) . unit <=> f
2. (>>= unit) <=> id
3. (>>= g) . (>>= f) <=> (>>= (>>= g) . f)
4. fmap f <=> (>>= unit . f)
5. join <=> (>>= id)
其中,式5. 利用函数(>>=)定义函数join:
join :: t t a -> t a
join = (>>= id)
范畴论定义 → Haskell定义:
1. (>>= f) . unit
<=> join . fmap f . unit
<=> join . unit . f
<=> f
2. (>>= unit)
<=> join . fmap unit
<=> id
3. (>>= g) . (>>= f)
<=> join . fmap g . join . fmap f
<=> join . join . fmap (fmap g) . fmap f
<=> join . fmap join . fmap (fmap g) . fmap f
<=> join . fmap (join . fmap g . f)
<=> (>>= (join . fmap g . f))
<=> (>>= (>>= g) . f)
4. fmap f
<=> fmap f . join . fmap unit
<=> join . fmap (fmap f) . fmap unit
<=> join . fmap (fmap f . unit)
<=> join . fmap (unit . f)
<=> (>>= unit . f)
5. join
<=> join . fmap id
<=> (>>= id)
Haskell定义 → 范畴论定义:
1. join . fmap join
<=> (>>= id) . fmap (>>= id)
<=> (>>= id) . (>>= unit . (>>= id))
<=> (>>= (>>= id) . unit . (>>= id))
<=> (>>= id . (>>+ id))
<=> (>>= (>>= id))
<=> (>>= id) . (>>= id)
<=> join . join
2. join . fmap unit
<=> (>>= id) . (>>= unit . unit)
<=> (>>= (>>= id) . unit . unit)
<=> (>>= id . unit)
<=> id
join . unit
<=> (>>= id) . unit
<=> id
3. unit . f
<=> (>>= unit . f) . unit
<=> fmap f . unit
4. join . fmap (fmap f)
<=> (>>= id) . (>>= unit . (>>= unit . f))
<=> (>>= (>>= id) . unit . (>>= unit . f))
<=> (>>= id . (>>= unit . f))
<=> (>>= (>>= unit . f))
<=> (>>= (>>= unit . f) . id)
<=> (>>= unit . f) . (>>= id)
<=> fmap f . join
5. (>>= f)
<=> (>>= id . f)
<=> (>>= (>>= id) . unit . f)
<=> (>>= id) . (>>= unit . f)
<=> join . fmap f
证明完毕