Look at each line separately.
class Functor f where
This declares a single parameter class called Functor ; satisfying this type will be called f .
fmap :: (a -> b) -> fa -> fb
Like any function definition, all variables of a free type are implicitly forall ed - they can be replaced with anything. However, thanks to the first line, f is in scope. So fmap has a signature like fmap :: forall a b. Functor f => (a -> b) -> fa -> fb fmap :: forall a b. Functor f => (a -> b) -> fa -> fb . In other words, each functor must have a fmap definition that can work for any a and b , and f must have the form (type type) * -> * ; that is, it must be a type that accepts another type, for example [] or Maybe or IO .
What you said is wrong; a not special, and if we had another function in Functor , she would not see the same a or b . However, the compiler uses the fa bit to figure out what type f should be. In addition, your Foo class is completely legal; I could specify an instance as follows
instance Foo (a -> b) where foo f _ = f
This satisfies foo :: a -> b -> a for any b ; note that b in Foo (a -> b) is different. Admittedly, this is not a very interesting example, but it is completely legal.
source share