Functors
The Maybe
data type looks like this.
data Maybe a = Nothing | Just a
Functors
You can’t just apply a normal function like (*5) to Maybe
data type. This is where fmap
comes handy. Because fmap
knows how to apply the function.
> fmap (*5) (Just 1)
Just 5
> fmap (*5) Nothing
Nothing
But.. How? Here is the answer! Functor
is a typeclass. It is any data type that defines how fmap
applies to it.
class Functor f where
fmap :: (a -> b) -> f a -> f b
Maybe
is a Functor
! This is the main reason that fmap
knows how to apply.
instance Functor Maybe where
fmap f (Just val) = Just (f val)
fmap f Nothing = Nothing
List
is also a Functor
!
instance Functor [] where
fmap = map
Practice
The data type WhyNot
defined as follows:
data WhyNot a = Nah | Sure a
deriving Show
Let’s make WhyNot
into an instance of Functor
and Monad
.
-- definitions
fmap :: Functor f => (a -> b) -> f a -> f b
(>>=) :: Monad m => m a -> (a -> m b) -> m b
return :: Monad m => a -> m a
instance Functor WhyNot where
fmap _ Nah = Nah
fmap f (Sure x) = f x
instance Monad WhyNot where
return Sure
Nah >>= _ = Nah
(Sure x) >>= f = f x