对纯净性的需求


19

我正在学习Haskell的Applicatives。在我看来(我可能错了),pure实际上并不需要该功能,例如:

pure (+) <*> [1,2,3] <*> [3,4,5]

可以写成

(+) <$> [1,2,3] <*> [3,4,5]

有人可以解释该pure函数提供的显式映射所带来的好处fmap吗?


1
您是正确的- pure f <*> x与完全相同fmap f x。我相信,有一些理由pure被列入Applicative,但我不完全知道为什么。
bradrn

4
我没有时间来回答这个问题,也不相信这无论如何都会是一个好的或完整的回答,但是有一个观察结果:pure允许一个人在应用计算中使用“纯”值。虽然,当你正确地观察,pure f <*> x是一样的f <$> x,不存在这样的等价条件,比方说f <*> x <*> pure y <*> z。(至少我不这么认为。)
Robin Zigmond

3
作为另一种理论上更合理的理由-有另一种表述将其与重要Monoid类别紧密相关-其中pure对应于Monoid的身份要素。(这表明,Applicative没有pure可能会很有趣,因为Semigroup- Monoid仍然需要使用它-不必使用身份。)实际上,现在我想起来了,我似乎想起了PureScript确实具有这样的“不带应用程序pure”类,尽管我没有(不知道它的作用是什么。)
罗宾·齐格蒙德

2
@RobinZigmond fmap (\f' x' z' -> f' x' y z') f <*> x <*> z,我想。该想法在Applicative文档中被称为“交换”定律。
HTNW

3
@RobinZigmond Applicativepure存在,因为Apply来自半群
duplode

Answers:


8

我现在的能力很强,所以不要花太多时间了,但是评论太久了。

pure在类型类中可能包含一些实际的原因,但是许多Haskell抽象是从理论基础上派生的,我认为情况Applicative也是如此。如文档所述,它是一个强大的松散单曲面函子(有关详细说明,请参阅https://cstheory.stackexchange.com/q/12412/56098)。我想,pure作为身份,就像return做了Monad(这是在endofunctors的范畴独异)。

考虑pureliftA2

pure :: a -> f a
liftA2 :: (a -> b -> c) -> f a -> f b -> f c

如果斜视一下,您也许可以想象这liftA2是一个二进制操作,文档也指出:

将二进制函数提升为动作。

pure,则为对应的身份。


6
究竟。Applicative没有,pure将是hm的半群函,而不是单半群
leftaroundabout

20

fmap并不总是削减它。具体来说,pure是什么让你介绍f(这里fApplicative)当你不已经拥有了它。一个很好的例子是

sequence :: Applicative f => [f a] -> f [a]

它获取产生值的“动作”列表,并将其转换为产生值列表的动作。如果列表中没有动作,会发生什么?唯一合理的结果是不产生​​任何值的动作:

sequence [] = pure [] -- no way to express this with an fmap
-- for completeness
sequence ((:) x xs) = (:) <$> x <*> sequence xs

如果您没有pure,则将被迫要求一个非空的动作列表。您肯定可以使它起作用,但这就像在谈论加法而没有提及0或在没有1的情况下进行乘法运算(正如其他人所说的那样,因为Applicatives是单曲面的)。您将反复遇到容易解决的极端情况,pure但必须通过对输入内容和其他创可贴的怪异限制来解决。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.