Tom*_*mer 18 haskell applicative
我正在学习 Haskell 的应用程序。在我看来(我可能错了)该pure功能并不是真正需要的,例如:
pure (+) <*> [1,2,3] <*> [3,4,5]
Run Code Online (Sandbox Code Playgroud)
可以写成
(+) <$> [1,2,3] <*> [3,4,5]
Run Code Online (Sandbox Code Playgroud)
有人可以解释该pure函数提供的显式映射的好处fmap吗?
HTN*_*TNW 20
fmap并不总是削减它。具体来说,当您还没有它时,pure它可以让您介绍f(where fis Applicative)。一个很好的例子是
sequence :: Applicative f => [f a] -> f [a]
Run Code Online (Sandbox Code Playgroud)
它需要一个产生值的“动作”列表,并将其转换为一个产生值列表的动作。当列表中没有操作时会发生什么?唯一合理的结果是一个不产生任何值的操作:
sequence [] = pure [] -- no way to express this with an fmap
-- for completeness
sequence ((:) x xs) = (:) <$> x <*> sequence xs
Run Code Online (Sandbox Code Playgroud)
如果您没有pure,您将被迫需要一个非空的操作列表。你绝对可以让它工作,但这就像谈论加法而不提到 0 或乘法而不提到 1(正如其他人所说,因为Applicatives 是幺半群)。您将反复遇到边缘情况,这些情况很容易解决,pure但必须通过对输入和其他创可贴的奇怪限制来解决。
我在这里处于我能力的边缘,所以不要把它看得太重,但评论有点太长了。
包含pure在类型类中可能有实际的原因,但许多 Haskell 抽象都源自理论基础,我相信也是如此Applicative。正如文档所说,它是一个强大的松散幺半群函子(详见https://cstheory.stackexchange.com/q/12412/56098)。我想这pure可以作为标识,就像returnfor Monad(它是内函子类别中的幺半群)一样。
考虑pure和liftA2:
pure :: a -> f a
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
Run Code Online (Sandbox Code Playgroud)
如果你稍微眯一下眼睛,你可能会想象这liftA2是一个二元运算,这也是文档中所说的:
将二元函数提升为动作。
pure,那么,就是对应的身份。