[英]What is the purpose of `pure` in Applicative Functor
符合Applicative类型类。 它位于Control.Applicative模块中,它定义了两个方法,
pure and <*>
。 它没有为它们中的任何一个提供默认实现,因此如果我们想要某些东西成为一个applicative functor,我们必须定义它们。
我试图了解谁在使用pure
函数。 我使用(<*>)
函数,其中applicative functor最有用。 但我不确定谁真的使用pure
。
我读过类似pure (+3) <*> Just 10
东西pure (+3) <*> Just 10
但它可以写成Just (+3) <*> Just 10
。
以上只是我有太多困惑。 定义pure
的真正目的是什么?我何时使用它(或)已经使用它?
<*> :: f (a -> b) -> fa -> fb
,此运算符接受applicative类型中的函数,以及applicative类型中的值。 因此,此运算符的第一个参数不能仅仅是一个函数,而是必须驻留在一个应用程序中。
pure
函数解决了此处可能出现的问题(例如,想要应用不存在于应用程序中的函数)。 它接受一个当前不在应用程序中的函数,并将其提升到应用程序中。 pure :: a -> fa
(+3) :: Int -> Int
,和Just 10 :: Maybe Int
,你不能这样评价(+3) <*> Just 10
因为类型不起作用; 必须将(+3)
提升为Maybe
applicative中的值。
对于Maybe a
, pure
的定义是pure = Just
,这就是为什么你可以编写pure (+3)
或Just (+3)
-
我会留给你看看<$>
运算符:-)请记住,每个Applicative都是一个Functor。
pure
就像Monoid
mempty
。 mempty
对于mappend
mempty
是中立的。 对于<*>
, pure
也是中性的(在某些情况下),它会将一些值提升到仿函数而没有任何效果或具有中性效果的提升。
这句话可以用四个属性形式化(复制/过去来自Applicative
文档):
pure id <*> v = v
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
pure f <*> pure x = pure (f x)
u <*> pure y = pure ($ y) <*> u
定义纯粹的真正目的是什么?我何时使用它(或)已经使用它?
好吧,基本上用于编写更通用的代码。 例如:
when :: Applicative f => Bool -> f () -> f ()
when p s = if p then s else pure ()
sequenceA_ :: Applicative f => [f a] -> f ()
sequenceA_ = foldr (*>) (pure ())
traverse_ :: Applicative f => (a -> f b) -> [a] -> f ()
traverse_ f = foldr ((*>) . f) (pure ())
此外,有时使用pure
更简单,然后隐式地将值包装到仿函数。 例如,比较:
pure 3 ~ StateT (\s -> Identity (3, s))
有几种情况可以使用pure
。
正如自由式的答案所示,当您不知道使用什么特定的Applicative
。
同样来自于自由泳,当它使用pure
时更方便。
除了在某些情况下编写起来更简单之外,它还可以使您的代码更加健壮。 在开发软件时,我的关键数据结构经常发展。 使用pure
而不是特定的构造函数有助于创建在重构期间可以保持不变的代码点。
Applicative
的实现不可用时。 有时,库不会为其数据类型导出构造函数。 相反,他们依靠函数来构建类型的有效实例。 使该类型成为Applicative
的成员是一种方法。 IO
Monad(Applicative)是构造函数不可用的类型的另一个示例。 相反,我们被迫使用pure
(又称return
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.