说一说'Monads'

说一说‘Monads

1.关于范畴论

范畴论是数学的一门学科,以抽象的方法来处理数学概念,将这些概念形式化成一组组“物件”及“态射”。范畴论是对数学的某些分支的更高阶的抽象化,所以被称为“一般化的抽象废话”。

  • 函子

    将范畴再抽象一次(范畴自身也是数学结构的一种),寻找在某一意义下会保持其结构的过程,我们把这一过程称为函子,这实际上是定义了一个包含“范畴和函子”的范畴,元件为范畴,态射为函子。

    一个从范畴 C 到范畴 D 的函子 F 被定义为:

    • C 中任意物件 X ,都有一个 D 中相应的物件 F(X) 与其对应;
    • C 中任意态射 f : XY ,都有一个 D 中相应的态射 F(f) : F(X) → F(Y) 与其对应;

    并使下列性质成立:

    • C 中任意的物件 X ,都有 F(idX) = idF(X) 。
    • C 中任意两个态射 f : XYg : YZ,都有 F(g · f) = F(g) · F(f) 。

    将范畴映射到自身的函子被称为“自函子(Endofunctor)”

  • 组成

    一个范畴‘C’是由三个部分组成:

    • 1.一个类ob(C),里面的元素称为“物件”

    • 2.一个类hom(C),其元素为“态射”或“箭号”。每个态射f 都只有一个“源物件”a 及一个“目标物件”b(其中ab 都在ob(C) 内),称之为“从ab 的态射”,标记为f : ab

    • 3.一个二元运算,称为“态射复合”,使得对任意三个物件abc,都会有hom(b, c) × hom(a, b) → hom(a, c)。两个态射f : abg : bc 的复合写做gfgf,并会符合下列两个公理:

      • 结合律:若f : abg : bch : cd,则h ∘ (gf) = (hg) ∘ f
      • 单位元:对任意物件x,总存在一个态射1x : xx(称为x单位态射),使得对每个态射f : ab,都会有1bf = f = f ∘ 1a

      (可以看出每个范畴只会有一个单位元,monad每个物件只会有一个单位态射

2.Haskell范畴论

Haskell中存在着这样的一种唯一的范畴Hask其满足我们上面所提到的范畴所满足的所有约定。

  1. 物件就是Haskell中的类型,注意Haskell中的类型是一个类,即是一个集合。
  2. 态射就是Haskell中的函数(function),如f :: Int -> Bool,函数f就是将Int这个物件的值映射到Bool物件的值上。
  3. 态射复合就是Haskell中函数的组合,比如func = f.g

​ 可以验证符合上面的两条公理。

由于Haskell中只有一个范畴,所以如果存在函子那么必然是映射到自身的自函子,那么Haskell中存不存在自函子呢?

  1. 首先要满足第一个条件:存在物件与物件之间的映射。在Haskell中,type constructor可以利用一个typeclass构造出其他的typeclass来,例如以下的定义:

    Tree
    data Tree a = Tip | Node a (Tree a) (Tree a)
    

    这里Node作为一类类型可以构造出Tree这种类型来。

  2. 第二个条件:态射与态射之间的映射。我们来看下面这种typeclass

    class Functor f where
      fmap:: (a -> b) -> f a -> f b
    

    typeclass fmap接受一个函数(物件与物件之间的映射),将其映射到另一个函数上(物件与物件的映射),所以说fmap是一个满足“态射与态射之间的映射”的一个typeclass。

3.monads

Monads是自函子范畴上的一个幺半群。