You are understanding this wrong: there are no subclasses concept playing anywhere.
When there is a class constraint like this: class (Functor f) => Applicative f
, it means that for defining some type to be an Applicative
instance, it should be already an instance of Functor
.
Consider the datatype Maybe
:
You define its Functor
instance like this:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
and its Applicative
instance like this:
instance Applicative Maybe where
pure = Just
(Just f) <*> (Just x) = Just (f x)
_ <*> _ = Nothing
As seen in the example above, you cannot define new function named fmap
in Applicative
instance just because it has its class constraint. The class constraint just tells you that Applicative
instance should already be an instance of Functor
typeclass. You have to define fmap
function while creating Functor
instance, because that's what the Functor
typeclass needs but not the Applicative
one.
Also, your typeclass should look like this:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
You don't need to put fmap
additionally into the Applicative
typeclass also. The class constraint implies that all types having Applicative
need to have fmap
defined.