This is easy to understand if you understand that you are fmap - above is a function, not a Maybe a value. The type Just is a -> Maybe a , so it falls into the functor (->) a , and not into the Maybe functor. Functor instance for functions looks like
instance Functor ((->) a) where fmap gf = g . f
therefore fmap just becomes a normal compound function! It means that
fmap (replicate 3) Just
coincides with
replicate 3 . Just
which most definitely has type a -> [Maybe a]
The explanation for a more typical type algebra should be to build the types and replace them until you can no longer. Let's start with our types, but with different variable names, to simplify their implementation:
fmap :: Functor f => (a -> b) -> (fa -> fb) replicate :: Int -> c -> [c] Just :: x -> Maybe x
Then for fmap (replicate 3) :
(replicate 3) :: c -> [c] fmap :: (a -> b) -> (fa -> fb)
So,
(c -> [c]) ~ (a -> b)
It means that
c ~ a [c] ~ b b ~ [a]
So, substituting back:
fmap (replicate 3) :: fc -> f [c]
Then what we fmap above is Just , which is of type
Just :: x -> Maybe x
What can be rewritten in the form of a prefix as
Just :: (->) x (Maybe x)
Or with lots of brackets if we really want
Just :: ((->) x) (Maybe x)
Then
Just :: ((->) x) (Maybe x) fmap (replicate 3) :: fc -> f [c]
It means that
((->) x) (Maybe x) ~ fc (->) x ~ f Maybe x ~ c [c] ~ [Maybe x]
So, substituting back:
fmap (replicate 3) :: ((->) x) (Maybe x) -> ((->) x) [Maybe x]
And back to infix notation
fmap (replicate 3) :: (x -> Maybe x) -> (x -> [Maybe x])
Then applying Just :
fmap (replicate 3) Just :: x -> [Maybe x]
Here I would like to emphasize that Maybe , which is a Functor , has nothing to do with this reduction, the only Functor is the Functor function. Lists are also Functor , but just because it is displayed in the replicate type does not mean that it is important in this case. Easy to confuse with function
fmap (replicate 3) . Just :: a -> Maybe [a]
but this is completely different due to the addition . .