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?
source to share
(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.
source to share
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.
source to share