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 ?
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"]