abelard2008
abelard2008

Reputation: 2084

the definition of Applicative instance implementation for Maybe (Haskell/LYAH)

Many times I tried to understand Functor and Monad in Haskell, but I failed. This time when I reached at LYAH's Applicative Functor, and thought I understood Applicative typeclasses, but I had some doubt about Applicative instance implementation for Maybe:

instance Applicative Maybe where  
pure = Just  
Nothing <*> _ = Nothing  
(Just f) <*> something = fmap f something

For the last line of above snippet, my understanding as follows:

(1) Just f is appropriated to f (a->b) in (<*>) :: f (a -> b) -> f a -> f b of class definition of Applicative, and f is appropriated to (a->b)

(2) something is appropriated to f a.

my question is from (2), why there is not written like Just something or the like?

In the Functor instance implementation for Maybe, there is fmap f (Just x) = Just (f x) and Just x is appropriated to f a of fmap :: (a -> b) -> f a -> f b.

for verifying my understanding, I changed something into Just something:

instance Applicative Maybe where  
pure = Just  
Nothing <*> _ = Nothing  
(Just f) <*> (Just something) = fmap f (Just something)

under gchi, I tried

Just (+3) <*> Just 9 

and got the same result Just 12, but when I tried

Just (++"hahah") <*> Nothing` 

I got the error

*** Exception: Functor.hs:(88,3)-(89,60): Non-exhaustive patterns in function <*>

I don't know why or what things I miss?

Upvotes: 3

Views: 677

Answers (2)

Franky
Franky

Reputation: 2421

(This is an extension of my comment and does not really answer the question)

This alternate definition is easier to grasp:

instance Applicative Maybe where  
    pure = Just  
    (Just f) <*> (Just x) = Just (f x)
    _        <*> _        = Nothing

I think you fell into the trap of interpreting too much out of the name something. I always try to name the variables f and x in the context of applicatives (in the context of <*>, to be precise), that's just what they are, a function and a value the function is applied to.

Upvotes: 3

alternative
alternative

Reputation: 13042

instance Applicative Maybe where  
pure = Just  
Nothing <*> _ = Nothing  
(Just f) <*> (Just something) = fmap f (Just something)

We can see whats wrong just by looking at the patterns! The first will match anything whose first parameter is Nothing, but the second will only match if it is both Just .... Nothing matches Just f and Nothing. Just because the first parameter is not Nothing doesn't mean the second has to be. If you really wanted to be explicit, you could write _ <*> Nothing = Nothing above the last line.

Upvotes: 3

Related Questions