我认为 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 x
与Maybe (a -> b)
、与x ~ (a -> b)
相结合。也就是说,Nothing
是可以用作 Maybe a
for any a
的值,包括函数类型。因此,这里是 <*>
的合法左手参数。
Maybe a
中的a
是一个类型变量,可以是任何类型!例如,Nothing
可以具有 Maybe Int
、Maybe [x]
或 Maybe (p -> q)
类型。
不要对变量名 a
在两个地方使用的事实感到困惑。 Nothing
类型中的a
与<*>
类型中的a
是完全不同的变量,恰好重名!
(这与你写 f x = x + 5
然后在其他地方 g x = "Hello, " ++ x
完全一样。在两个地方使用 x
并不重要,因为它们在不同的地方范围。与此类型中的 a
相同。不同的范围,因此它们是不同的变量。)
我目前正在与 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 x
与Maybe (a -> b)
、与x ~ (a -> b)
相结合。也就是说,Nothing
是可以用作 Maybe a
for any a
的值,包括函数类型。因此,这里是 <*>
的合法左手参数。
Maybe a
中的a
是一个类型变量,可以是任何类型!例如,Nothing
可以具有 Maybe Int
、Maybe [x]
或 Maybe (p -> q)
类型。
不要对变量名 a
在两个地方使用的事实感到困惑。 Nothing
类型中的a
与<*>
类型中的a
是完全不同的变量,恰好重名!
(这与你写 f x = x + 5
然后在其他地方 g x = "Hello, " ++ x
完全一样。在两个地方使用 x
并不重要,因为它们在不同的地方范围。与此类型中的 a
相同。不同的范围,因此它们是不同的变量。)