[英]Haskell: Understanding the pure function for Applicative functors
我正在学习Applicative Functors,并且pure函数具有以下类型声明:
pure :: a -> f a
我知道pure函数可以接受任何类型的值,并返回其中包含该值的适用值。 因此,如果适用实例是Maybe
,则pure 3
会得到Just 3
。
但是,当您将纯值应用到应用值中已经包含的值时会发生什么? 例如,如果您执行pure Just 3
怎样?
如果将纯值应用于已经在应用值内的值,会发生什么?
它只是包裹在一个附加层中。 最终结果是一个嵌套在另一个应用程序值内的应用程序值。
例如,如果您执行
pure Just 3
怎样?
这可能是一个有趣的问题,尽管可能并非出于您的意思。 这里的重点是要区分pure (Just 3)
(这可能是您的意思)与pure Just 3 = (pure Just) 3
(您写的是)。 这给出了两种情况:
pure (Just 3)
只是将pure
应用于值Just 3
,正如我上面所讨论的,它给出了Just (Just 3)
,它是一个嵌套的应用值。 (pure Just) 3
是一个有趣的案例。 回想一下pure
和Just
的类型:
pure :: Applicative f => a -> fa Just :: a -> Maybe a -- so: pure Just :: Applicative f => f (a -> Maybe a)
换句话说, pure Just
取功能Just
和包装它的应用价值内。
接下来,我们要采用pure Just
并将其应用于值3
。 但是我们不能这样做,因为f (a -> Maybe a)
是一个值,而不是一个函数! 因此(pure Just) 3
应该导致类型错误。
…除了事实证明可以进行类型检查! 因此,我们缺少了一些东西。 在这种情况下,事实证明有一个函数的应用实例:
instance Applicative ((->) r) where pure x = \\r -> x (<*>) = _irrelevant_here
语法有点可笑,但是它基本上意味着r -> ...
是可应用的。 这个特定的实例称为Reader monad ,它被广泛使用。 (有关该特定数据类型的,例如参见这里或这里 。)的想法是, r -> a
可以计算的a
给定的r
输入; 在这种情况下, pure x
创建一个忽略其输入并始终返回x
的函数,并且f <*> x
将r
输入馈入f
和x
,然后将两者组合。 在这种情况下,我们仅使用pure
,因此很容易手动评估(pure Just) 3
:
(pure Just) 3 = (\\r -> Just) 3 = Just
因此,这里的想法是, pure
将Just
包装在一个应用值中,在这种情况下,它恰好是一个函数。 然后,将此函数应用于3
,该函数将摆脱包装器以显示原始Just
。
首先,pure具有以下类型:
pure :: Applicative f => a -> f a
为简化起见,请考虑f
:k f
f :: * -> *
a
的种类是*
然后类型a
,仅仅是a
,任何a
最多态性所有的(但有一种*
记得了)。 因此,您实际上并不在乎a的值,只是有一个限制,那就是typeclass
Applicative和f
的种类(请记住* -> *
)
所以在这种情况下:
gchi> pure 3 :: Maybe Int
ghci> Just 3
这里f
Maybe
是, a
是3
以同样的方式
gchi> pure $ Just 3 :: Maybe (Maybe Int)
gchi> Just (Just 3)
在这里f
又Maybe
是,而a
Just 3
然后您可以将类型更改为pure:
gchi> pure 3 :: [Double]
ghci> [3.0]
在这里, f
是[], a
是3
同样的方式
ghci> pure [3] :: [[Double]]
ghci> [[3.0]]
终于在这里, f
又是[]
, a
是[3]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.