Reputation: 55
I just started learning haskell and I have this code which won't compile:
data Foo a b = Foo a b deriving (Show)
instance Functor (Foo a) where
fmap f (Foo a b) = Foo (f a) b
If I change the fmap implementation a bit to this, then it works:
fmap f (Foo a b) = Foo a (f b)
Can someone explain why?
Upvotes: 2
Views: 65
Reputation: 105945
If we have
data Foo a b = Foo a b
and
instance Functor (Foo k) where
then for all functions you define in your typeclass, the first parameter a
is fixed. With that single line, you tell the world that for any k
, Foo k
will be a functor. However, that means that your first parameter cannot be mapped over with fmap
:
fmap :: Functor f => (a -> b) -> f a -> f b
Remember, our functor will be Foo k
. So we will end up with
fmap :: (a -> b) -> (Foo k) a -> (Foo k) b
-- ^^^^^^^ ^^^^^^^
-- | |
-- +-------+-----+
-- |
-- f from above
When you've used fmap
on the first argument, you created the following implementation of fmap
:
fmap :: (a -> b) -> (Foo a) z -> (Foo b) z
-- ^^^^^^^ ^^^^^^^
-- | |
-- +-------+-----+
-- |
-- err, those 'f's differ
Which is why your first variant didn't work, but the latter did.
Upvotes: 4