About some basic functor in haskell

Why does this fmap (replicate 3) Just "JOHN" return this [Just "JOHN",Just "JOHN",Just "JOHN"] ? I know that fmap (replicate 3) Just "JOHN" is equivalent with fmap (replicate 3) Just $ "JOHN", but why does that even compile ? How can we apply fmap to
Just which isn’t even of concrete type ?

>Solution :

A functor f is a type constructor with an associated function fmap that "lifts" a function of type a -> b to be a function of type f a -> f b.

Both Maybe and (->) r (the partially applied function constructor) are functors.

-- When possible, apply the function to the wrapped value 
-- and wrap the result. Otherwise, return Nothing
instance Functor Maybe where
   fmap f Nothing = Nothing
   fmap f (Just x) = Just (f x)

-- Compose the two functions
instance Functor ((->) r) where
    fmap f g = f . g

Your expression uses the function instance on the two functions replicate 3 :: a -> [a] and Just :: a -> Maybe a:

fmap (replicate 3) Just "JOHN" == (replicate 3) . Just $ "JOHN"
                               == (replicate 3) (Just "JOHN")
                               == [Just "JOHN", Just "JOHN", Just "JOHN"]

What you likely intended was to map replicate 3 over the value Just "JOHN" :: Maybe String, making use of the Maybe instance.

fmap (replicate 3) (Just "JOHN") == Just (replicate 3 "JOHN")
                                 == Just ["JOHN", "JOHN", "JOHN"]

Leave a Reply