inaba
inaba

Reputation: 55

Implementing functor typeclasses

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

Answers (1)

Zeta
Zeta

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

Related Questions