cen*_*980 1 haskell functional-programming applicative
我正在学习Applicative Functors,并且pure函数具有以下类型声明:
pure :: a -> f a
Run Code Online (Sandbox Code Playgroud)
我知道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 -> f a
Just :: a -> Maybe a
-- so:
pure Just :: Applicative f => f (a -> Maybe a)
Run Code Online (Sandbox Code Playgroud)
换句话说,pure Just采用该函数Just并将其包装在一个应用值内。
接下来,我们要采用pure Just并将其应用于value 3。但是我们不能这样做,因为它f (a -> Maybe a)是一个值,而不是一个函数!因此(pure Just) 3应导致类型错误。
…除了事实证明可以进行类型检查!因此,我们缺少了一些东西。在这种情况下,事实证明有一个函数的应用实例:
instance Applicative ((->) r) where
pure x = \r -> x
(<*>) = _irrelevant_here
Run Code Online (Sandbox Code Playgroud)
语法有点有趣,但是它基本上意味着它r -> ...是可应用的。这个特定的实例称为Reader monad,它被广泛使用。(有关此特定数据类型的更多信息,请参见此处或此处。)这个想法是r -> a可以计算a给定的r输入;例如,在这种情况下,pure x创建一个忽略其输入并x始终返回的函数,并将输入f <*> x提供给和,然后将r两者合并。在这种情况下,我们仅使用,因此手工评估很容易:fxpure(pure Just) 3
(pure Just) 3
= (\r -> Just) 3
= Just
Run Code Online (Sandbox Code Playgroud)
因此,这里的想法是pure包装Just一个应用值,在这种情况下恰好是一个函数;然后,我们将此功能应用于3,从而摆脱了包装程序,从而揭示了原始内容Just。
首先, pure 有以下类型:
pure :: Applicative f => a -> f a
Run Code Online (Sandbox Code Playgroud)
为了让事情更简单,想想那种 f
:k f
f :: * -> *
Run Code Online (Sandbox Code Playgroud)
和那种a是*
那么 , 的类型a就是a, any a,是所有类型中最多态的(但*请记住)。所以你并不真正关心 a 的值,你只是有一个限制,那就是typeclassApplicative,以及那种f(记住* -> *)
所以在这种情况下:
gchi> pure 3 :: Maybe Int
ghci> Just 3
Run Code Online (Sandbox Code Playgroud)
这f是Maybe并且a是3
以同样的方式
gchi> pure $ Just 3 :: Maybe (Maybe Int)
gchi> Just (Just 3)
Run Code Online (Sandbox Code Playgroud)
这里f再次Maybe和a是Just 3
您可以稍微将类型更改为纯:
gchi> pure 3 :: [Double]
ghci> [3.0]
Run Code Online (Sandbox Code Playgroud)
在这里,f是 [],并且a是3
同样的方法
ghci> pure [3] :: [[Double]]
ghci> [[3.0]]
Run Code Online (Sandbox Code Playgroud)
终于f又来了,现在[]和a现在 [3]