Haskell的Monad定律如何从自函子范畴的Monoid定律推导而来?
范畴论Monoid定律与Haskell Monad定律的等价性证明
自函子范畴上的Monoid定律对应交换图如下:
对应的代数表达式为:
- 结合律:
join (join x) = join (fmap join x) - 左单位律:
join (return x) = x - 右单位律:
join (fmap return x) = x
前置约定
我们默认以下基础关系成立:
- Haskell中Monad的绑定操作
>>=可通过函子映射fmap和自函子乘法join等价定义:m >>= k = join (fmap k m) - 所有讨论的实例满足函子定律与自然变换的基本性质
左单位律等价推导
Haskell Monad左单位律:return a >>= k = k a
- 按
>>=定义展开左侧:return a >>= k = join (fmap k (return a)) - 根据自然变换性质,
fmap f (return x) = return (f x),代入得:join (return (k a)) - 应用范畴论左单位律
join (return x) = x,直接化简为k a,与右侧完全相等
右单位律等价推导
Haskell Monad右单位律:m >>= return = m
- 按
>>=定义展开左侧:m >>= return = join (fmap return m) - 直接对应范畴论右单位律
join (fmap return x) = x,代入x=m即可得结果m,与右侧完全相等
结合律等价推导
Haskell Monad结合律:m >>= (\x -> k x >>= h) = (m >>= k) >>= h
化简左侧
- 展开外层
>>=:join (fmap (\x -> k x >>= h) m) - 展开内层
>>=:join (fmap (\x -> join (fmap h (k x))) m) - 按函子复合性质拆分fmap:
join (fmap join (fmap (fmap h . k) m)) - 应用范畴论结合律
join (fmap join x) = join (join x),代入得:join (join (fmap (fmap h . k) m))
化简右侧
- 展开外层
>>=:join (fmap h (m >>= k)) - 展开内层
>>=:join (fmap h (join (fmap k m))) - 应用join的自然变换性质
fmap f . join = join . fmap (fmap f),代入得:join (join (fmap (fmap h) (fmap k m))) - 按函子复合性质合并fmap:
join (join (fmap (fmap h . k) m))
左右两侧化简结果完全一致,结合律等价。
内容的提问来源于stack exchange,提问作者Ziyang Liu
相关产品推荐
相关产品推荐

