我认为 Haskell 中 Applicative Maybe 实例的默认定义中存在类型不匹配

I think there is a type mismatch in default definition in instance Applicative Maybe in Haskell

我目前正在与 Hutton 教授的 "Programming in Haskell" 一起研究 Haskell,我发现关于 Maybe 的定义有些奇怪,作为 class Applicative 的一个实例。

GHC.Base中,实例Applicative Maybe定义如下:

instance Applicative Maybe where
  pure = Just

  Just f  <*> m       = fmap f m
  Nothing <*> _m      = Nothing

令我困扰的是将 Nothing <\*> _ 的值定义为 Nothing 的行。 Nothing 属于 Maybe a 类型,其中运算符 <*> 实际上需要 f (a -> b)(在本例中为 Maybe (a -> b))作为其第一个参数的类型。因此,这是类型不匹配,Haskell 应该抱怨。但是,这被接受为默认定义,因此 Haskell 不会在我认为应该抱怨的地方抱怨它。

我错过了什么?

让我们通过重新标记类型变量使事情更清楚:

Nothing :: Maybe x

类型Maybe xMaybe (a -> b)、与x ~ (a -> b)相结合。也就是说,Nothing 是可以用作 Maybe a for any a 的值,包括函数类型。因此,这里是 <*> 的合法左手参数。

Maybe a中的a是一个类型变量,可以是任何类型!例如,Nothing 可以具有 Maybe IntMaybe [x]Maybe (p -> q) 类型。 不要对变量名 a 在两个地方使用的事实感到困惑。 Nothing类型中的a<*>类型中的a是完全不同的变量,恰好重名!

(这与你写 f x = x + 5 然后在其他地方 g x = "Hello, " ++ x 完全一样。在两个地方使用 x 并不重要,因为它们在不同的地方范围。与此类型中的 a 相同。不同的范围,因此它们是不同的变量。)