`< *>`和`< $>`之间的关系

时间:2017-11-14 04:05:56

标签: haskell functor applicative

根据Haskell Wikibookclasses<$>之间的以下关系成立:

<*>

他们声称人们可以证明这个定理是算子和适用法律的结果。

我不知道如何证明这一点。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:3)

Functor和Applicative Laws

让我们从仿函数和适用法则开始。 Let's take a look at these laws presented in the Haskell Wikibook

fmap id = id                   -- 1st functor law
fmap (g . f) = fmap g . fmap f -- 2nd functor law

现在我们应该看看适用法律。

pure id <*> v = v                            -- Identity
pure f <*> pure x = pure (f x)               -- Homomorphism
u <*> pure y = pure ($ y) <*> u              -- Interchange
pure (.) <*> u <*> v <*> w = u <*> (v <*> w) -- Composition
  

身份法则认为应用pure id态射不会做任何事情,就像使用普通id函数一样。

     

同态定律表示将“纯”函数应用于“纯”值与将函数应用于正常方式的值然后在结果上使用纯值相同。从某种意义上说,这意味着纯粹的保留功能应用。

     

交换法规定,将态射应用于“纯”值pure y与将pure ($ y)应用于态射相同。没有惊喜 - 正如我们在高阶函数章节中看到的那样,($ y)是将y作为参数提供给另一个函数的函数。

     

组成法规定,pure (.)类似于(.)组成函数的方式组成态射:将组合态射pure (.) <*> u <*> v应用于w会产生与应用{{1}相同的结果将u应用于v的结果。

为了证明这种关系,我们需要证明什么

Per @ benjamin-hodgson

  

足以证明w因适用法律而遵守fmap f x = pure f <*> x法律。

我们只需要证明fmap id = id遵守fmap f x = pure f <*> x法律的原因是因为可以证明第二个仿函数法可以遵循第一定律。我已经简要介绍了这个证明,但Edward Kmett有一个更详细的版本here

Wadler Theorems for Free的第3.5节提供了关于函数fmap id = id的一些工作。基于自由定理的思想,为函数显示的任何东西都适用于相同类型签名的任何其他函数。由于我们知道列表是仿函数,因此map的类型类似于map :: (a -> b) -> [a] -> [b]的类型,这意味着Wadler的所有地图也适用于fmap。

Wadler关于地图的结论导致了关于fmap的这个定理:

给定函数fmap :: Functor f => (a -> b) -> [a] -> [b]fgkh然后g . h = k . f $map g . fmap h = fmap k . $map' f$map给定仿函数的“自然”映射函数。这个定理的完整证明有点冗长,但Bartosz Milewski提供了一个很好的overview

我们需要两个引理来证明第二个仿函数法是第一个的结果。

引理1

给定fmap id = id --the first functor law然后fmap f = $map f

fmap f = $map id . fmap f   --Because $map id = id
= fmap id . $map f          --Because of the free theorem with g = k = id and h = f
= $map f                    --Because of the first functor law

所以fmap f = $map ffmap = $map

引理2

鉴于f . g = id . (f . g)

id . v = v显而易见

全部放在一起

给定fmap id = id然后fmap f . fmap g = fmap (f . g)

fmap f . fmap g = $map f . fmap g  --Because of lemma 1
= fmap id . $map (f . g)           --Because of the free theorem for fmap and lemma 2
= $map (f . g)                     --Because of the first functor law
= fmap (f . g)                     --Because $map = fmap

因此,如果我们能够证明第一个仿函法是有效的,那么第二个也将成立。

证明关系

表明我们需要适用身份法。看看法律,我们pure id <*> v = v,并从我们试图证明的等价f <$> x = pure f <*> x。如果我们让x = id那么应用身份法告诉我们,等效的右边是id x,第一个Functor法则告诉我们左边是id x

f <$> x = pure f <*> x
id <$> x = pure id <*> x  -- Substitute id into the general form
id <$> x = x              -- Apply the applicative identity law
id x = x                  -- Apply the first functor law
x = x                     -- simplify id x to x

我们已经证明fmap f x = pure f <*> x通过适用法律遵守第一个仿函数法。