繁体   English   中英

Haskell:了解应用函子的纯函数

[英]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是一个有趣的案例。 回想一下pureJust的类型:

     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 <*> xr输入馈入fx ,然后将两者组合。 在这种情况下,我们仅使用pure ,因此很容易手动评估(pure Just) 3

     (pure Just) 3 = (\\r -> Just) 3 = Just 

    因此,这里的想法是, pureJust包装在一个应用值中,在这种情况下,它恰好是一个函数。 然后,将此函数应用于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是, a3

以同样的方式

gchi> pure $ Just 3 :: Maybe (Maybe Int)
gchi> Just (Just 3)

在这里fMaybe是,而a Just 3

然后您可以将类型更改为pure:

gchi> pure 3 :: [Double]
ghci> [3.0]

在这里, f是[], a3

同样的方式

ghci> pure [3] :: [[Double]]
ghci> [[3.0]]

终于在这里, f又是[]a是[3]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM