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

时间:2018-08-13 04:00:00

标签: haskell types applicative

我目前正在与赫顿教授的“在Haskell中编程”一起研究Haskell,我发现Maybe作为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不会在我认为应该的位置抱怨它。

我想念什么?

2 个答案:

答案 0 :(得分:11)

<*>中的a是一个类型变量,根本可以是任何类型!例如,Maybe a的类型可以为NothingMaybe IntMaybe [x]。  不要为变量名Maybe (p -> q)在两个地方使用而感到困惑。 a类型的aNothing类型的a是完全不同的变量,并且恰好具有相同的名称!

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

答案 1 :(得分:4)

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

Nothing :: Maybe x

类型Maybe xMaybe (a -> b)x ~ (a -> b)统一。也就是说,Nothing是可用作 any Maybe a的{​​{1}}的值,包括函数类型。因此,这里是a的合法左手参数。