Applicative Functor 纯匹配未包装

Applicative functors pure matching not wrapped

我正在学习应用函子。在应用程序 Maybesource 中,pure 函数如下所示:

instance Applicative Maybe where
    pure = Just
    ...etc

展开参数后,我认为它看起来像:

pure x = Just x

当我调用 pure (Just 5) 时,它 return 是 Just 5

不应该returnJust (Just 5)吗?

同样,对于List

instance Applicative [] where  
    pure x = [x]

当我调用 pure [4,5,6] 时 returns [4,5,6].

从签名来看,pure [4,5,6] 应该 return [[4,5,6]].

谁能简单解释一下这里发生了什么?


等等,我想我明白了 - 因为没有提供上下文,pure [4,5,6] 没有将 Applicative 用于 List,它只是使用一般情况和 returning 相同的值。这是正确的吗?

pure 是一个重载函数。它接受任何类型的值 a,并将其包装到应用仿函数 f.

ghci> :t pure
pure :: Applicative f => a -> f a

f 由上下文决定。如果您将 pure x 传递给需要 Maybe 的函数,类型检查器将推断 f ~ Maybe 和 select Maybe 的 [= 实例22=] 和 pure x 将计算为 Just x。同样,如果将 pure x 传递给列表函数,类型检查器将使用 []Applicative 实例,而 pure x 将 return 一个单例列表。

ghci> :t map
map :: (a -> b) -> [a] -> [b]  -- map is a list function
ghci> map (+1) (pure 4)        -- so when we pass in (pure 4)
[5]                            -- it means a singleton list

对于您的情况,我猜您是在 GHCI 提示符下输入 pure x。如果您不提供任何上下文(例如将列表函数应用于 pure x),GHCI 将默认假设您打算使用 IOApplicative 实例,为此 pure x 是一个什么都不做的 IO 动作 returning x。 GHCI 然后尽职地执行该 IO 操作。

ghci> pure 'a'
'a'
ghci> pure (Just 3)
Just 3

如果类型检查器无法根据您的代码查看上下文,您可以使用类型注释手动声明上下文。

ghci> pure "hello" :: Maybe String
Just "hello"
ghci> pure (Just 3) :: Maybe (Maybe Int)
Just (Just 3)
ghci> pure [1,2,3] :: [[Int]]
[[1,2,3]]