I am currently studying Haskell with Prof. Hutton's "Programming in Haskell", and I found something strange regarding the definition of Maybe as an instance of the class Applicative.
In GHC.Base, the instance Applicative Maybe is defined as follows:
instance Applicative Maybe where
pure = Just
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
It is the line which defines the value of Nothing <\*> _ as Nothing that bothers me. Nothing is of type Maybe a, where the operator <*> actually requires f (a -> b) (in this case, Maybe (a -> b)) as its first argument's type. Therefore, this is a type mismatch, which Haskell should complain about. However, this is accepted as a default definition, and therefore Haskell does not complain about it where I think it should.
What am I missing?
The a in Maybe a is a type variable, and can be any type at all! So Nothing can have the type Maybe Int, or Maybe [x], or Maybe (p -> q), for example.
Don't get confused by the fact that the variable name a is used in two places. The a in the type of Nothing is a completely different variable from the a in the type of <*>, and just happens to have the same name!
(That's exactly the same as if you wrote f x = x + 5 and then elsewhere, g x = "Hello, " ++ x. The use of x in both places doesn't matter, because they are in different scopes. Same with the a in this types. Different scopes, so they are different variables.)
Let's make things clearer by relabeling a type variable:
Nothing :: Maybe x
The type Maybe x unifies with Maybe (a -> b), with x ~ (a -> b). That is, Nothing is a value that can used as Maybe a for any a, including a function type. Thus it is a legal left-hand argument for <*> here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With