Defining Applicative instance Implementation for Maybe (Haskell / LYAH)

Many times I've tried to understand Functor and Monad in Haskell, but I have failed. This time, when I got to the LYAH Applicative Functor and thought I understood Applicative typeclasses

, but I had some doubts about implementing an applicative instance for Maybe:

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

      

For the last line of the above snippet, I understand the following:

(1) Just f

assigned f (a->b)

in (<*>) :: f (a -> b) -> f a -> f b

Applicative class definitions and f

assigned(a->b)

(2) is something

assigned f a

.

my question is from (2), why is it not written like Just something

or the like?

The Functor instance implementation for Maybe exists fmap f (Just x) = Just (f x)

and is Just x

assigned f a

from fmap :: (a -> b) -> f a -> f b

.

to confirm my understanding, I changed something

to 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 error

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

      

I don't know why and what am I missing?

+3


source to share


2 answers


(This is an extension of my comment and doesn't really answer the question)

This alternative definition is easier to understand:



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

      

I think you are trapped in too much to interpret the name something

. I always try to name variables f

and x

in the context of the applications (more precisely, in the context <*>

), what exactly they are, the functions and the values ​​to which the function is applied.

+3


source


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

      



We can see what's wrong just by looking at the templates! The first will match everyone whose first parameter is Nothing

, but the second will only match if it's equal Just ...

. Nothing matches Just f

and Nothing

. Just because the first parameter does Nothing

n't mean that the second should be. If you really want to be explicit, you can write _ <*> Nothing = Nothing

above the last line.

+3


source







All Articles