Reputation: 2084
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
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
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