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

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



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



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:


GHC.Base


Applicative Maybe


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.


Nothing <*> _


Nothing


Nothing


Maybe a


<*>


f (a -> b)


Maybe (a -> b)



What am I missing?




2 Answers
2



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!


a


Maybe a


Nothing


Maybe Int


Maybe [x]


Maybe (p -> q)


a


a


Nothing


a


<*>



(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.)


f x = x + 5


g x = "Hello, " ++ x


x


a





Oh, I get it! So, 'a' in "Maybe a" is a very broad generalization of any type that can be given to the constructor function "Maybe". Thanks a lot!
– Namudon'tdie
Aug 13 at 4:13



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.


Maybe x


Maybe (a -> b)


x ~ (a -> b)


Nothing


Maybe a


a


<*>





Thank you for your answer. Small follow-up question here: should I read x ~ (a -> b) as "the variable x is associated with type (a -> b)"?
– Namudon'tdie
Aug 13 at 4:15





@Namudon'tdie: x ~ y is a type equality constraint. Informally, people use it to mean “the type x is equal to the type y”; in Haskell, you can use this syntax as a typeclass constraint when certain extensions are enabled (e.g. GADTs or TypeFamilies). It’s mainly useful for controlling typeclass instance resolution and aiding type-level programming.
– Jon Purdy
Aug 13 at 6:04


x ~ y


x


y


GADTs


TypeFamilies






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard