代码之家  ›  专栏  ›  技术社区  ›  Casebash

单子定律的解释

  •  31
  • Casebash  · 技术社区  · 15 年前

    a gentle introduction to Haskell ,有以下单子定律。有人能直观地解释他们的意思吗?

    return a >>= k             = k a
    m >>= return               = m
    xs >>= return . f          = fmap f xs
    m >>= (\x -> k x >>= h)    = (m >>= k) >>= h
    

    以下是我的解释:

    1. 我们希望返回函数 a 到函数。

    2. 未包装的输出 m 传递给 return 这就重写了它。一元的本性保持不变。所以它和原来的单子是一样的。

    3. f 然后重拍。一元的本性保持不变。这是我们将一个正规函数转换为一元函数时所期望的行为。

    4 回复  |  直到 7 年前
        1
  •  49
  •   j3h John L    13 年前

    你的描述很好。一般来说,人们会说三个单子定律,分别是1,2和4。你的第三定律稍有不同,我稍后再谈。

    对于三个单子定律,我发现用克莱斯利作曲更容易直观地理解它们的含义:

    -- defined in Control.Monad
    (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
    mf >=> n = \x -> mf x >>= n
    

    现在法律可以写成:

    1) return >=> mf = mf                  -- left identity
    2) mf >=> return = mf                  -- right identity
    4) (f >=> g) >=> h = f >=> (g >=> h)   -- associativity
    

    1) 左恒等式法则-返回值不会改变值,也不会在monad中执行任何操作。

    两个身份法基本上说的是同一件事,但它们都是必要的,因为 return

    现在是第三定律。这个定律本质上说,函子实例和你的单子实例在把一个函数提升到单子中时的行为是一样的,两个实例都不是单子。如果我没弄错的话,当一个单子遵守其他三条定律,函子实例遵守函子定律,那么这个陈述永远是正确的。

    Haskell Wiki Typeclassopedia 也是一个很好的参考。

        2
  •  24
  •   C. A. McCann Ravikant Cherukuri    15 年前

    属性集。正如约翰所说,你提到的第三定律稍有不同,但下面是其他定律的分解方法:

    绑定到单子的函数就像普通函数一样组成。

    a -> m b . 想想 return id (<=<) (.) ,单子定律是这些的翻译:

    1. id . f f
    2. f . id 相当于
    3. (f . g) . h 相当于 f . (g . h)

    在很大程度上,你可以把额外的一元结构看作是一系列与一元值相关联的额外行为;例如 Maybe Nothing 继续前进 Just . 结合两个一元行为,然后基本上串联的行为序列,他们举行。

    从这个意义上说, 返回 (>=>) 是串联。所以,单子定律是这些的翻译:

    1. [] ++ xs xs
    2. xs ++ [] 相当于 xs型
    3. (xs ++ ys) ++ zs xs ++ (ys ++ zs)

    这三条定律描述了一个可笑的共同模式,不幸的是,Haskell不能完全概括地表达出来。如果你有兴趣, Control.Category 给出了“看起来像函数组合的东西”的一般化,而 Data.Monoid

        3
  •  12
  •   Matthias Braun AdamSkywalker    7 年前

    依据 do 对一元运算序列进行分组的块。

        do                          do
                                      y <- do
          x <- m                             x <- m
          y <- k x          <=>              k x
          h y                         h y
    

    这允许返回一元值的函数正常工作。

        4
  •  4
  •   Paul Johnson    15 年前

    最后一条定律是bind的结合性。这意味着你采取了如下措施:

    do
       x <- foo
       bar x
       z <- baz
    

    把它变成

    do
       do
          x <- foo
          bar x
       z <- baz
    

    有时单子并不完全遵循这些规律,特别是当出现某种底部值时。只要它被记录在案并且“道德上是正确的”(也就是说,非底线价值遵循法律,或者结果在其他方面被认为是等价的),那就可以了。

    推荐文章