一个温和的介绍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 因此,它的元性是微不足道的。当我们结合到一个功能,有没有一元的影响,它应该只是传递 a 的功能。

  2. 解开输出 m 传递到 return 这rewraps。这一元性的保持相同。所以它是相同的原始单.

  3. 解开价值传递给 f 然后重新压缩.这一元性的保持相同。这是行为的期望,当我们改变一个功能正常进入一个一元的职能。

  4. 我没有解释这项法律。这并说,单必须是"几乎的关联"。

有帮助吗?

解决方案

你的描述似乎很好。通常人们说话的三单法律,你已经为1、2、和4。你的第三个法略有不同,我将得到以后。

三单法律,我发现它很容易得到一个直观地了解他们是什么意思,当他们重新写入使用Kleisli组成:

-- 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)留身份法返回的一个价值不变的价值和没有做任何事情的单.

2)正确的身份法返回的一个价值不变的价值和没有做任何事情的单.

4)结合性-元组成的关联(我喜欢KennyTM的答案)

两个身份法律基本上说同样的事情,但它们都是必要的,因为 return 应该有身份的行为在两个侧面结合经营者。

现在的第三项法律。这项法律本质上说,两者的函的实例和你单实例的行为方式相同时提升功能进入单,也没有任何东西一元.如果我没有记错的话,这种情况下,当一个单遵守其他三项法律和函子实例的遵守函的法律,则该声明将永远是真实的。

很多这种来自 Haskell Wiki.的 Typeclassopedia 是一个很好的参考。

其他提示

没有分歧与其他的答案,但它可能有助于思考的单的法律如实描述 两个 集的性质。作为约翰说,第三定律说是稍有不同,但这里的别人如何可以拆除:

功能结合到一个单撰写就像普通的职能。

正如在约翰回答,是什么叫Kleisli箭头用一个单一功能的类型 a -> m b.想想 return 作为 id(<=<) 作为 (.), 和单的法律翻译:

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

序列的一元的追加影响喜欢的名单。

大部分,可以认为额外元结构作为一系列额外的行为相关的元价值;例如 Maybe 被"放弃"为 Nothing 和"继续"于 Just.合并两个单子的行动,然后基本上将序列的行为他们举行。

在这个意义上说, return 又是一个身份--空行动,类似于一个空的行为列表--和 (>=>) 是串联。因此,单的法律翻译:

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

这三个法律描述了一个可笑的共同模式,其Haskell不幸的是,不能完全表达的完全普遍性。如果你有兴趣, Control.Category 给出了一个概括的"事情,看起来像功能组成",同时 Data.Monoid 概括后一种情况下,那里没有类型参数的参与。

在条款 do 符号,第4条意味着我们可以添加一个额外的 do 块组序列的单子操作。

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

这一功能允许返回元价值的正常工作。

第三定律说,"返回"只有一个包裹值和没有别的。所以你可以消除的"返回"的呼吁没有变化的语义学。

最后一个法是关联性对于结合。这意味着你需要的东西,如:

do
   x <- foo
   bar x
   z <- baz

并把它变成

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

而意思又不改变。当然你不会做到这一点,但是你可能想要把内"做"的规定在一个"如果"的发言,并希望它意味着同时将"如果"是真实的。

有时候单元的不完全按照这些法律,特别是当某些种类的底价值时发生。那好吧只要它的记录是"在道义上正确的"(即法律都遵循非底值,或结果被认为等同于某些其他方式)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top