Try mentally (or with a text editor) to populate the types specified in the class definition with the type that you used in the instance.
From:
class Print a where print :: a -> String
and
data A t = A t
we want
instance Print A
So, substituting a in the type class definition for a , we say it is instnace, we get the following:
class Print a where print :: a -> String
Ooh A -> String does not make sense as a type, since the function type of the arrow takes the type on the left and the type on the right and gives you the type of the function. But a not a type since you declared a with data A t ; A t is a type for any type of t , but a is a type constructor. It can create a type if you apply it to a type, but a by itself is something else. So you can make A t into a Print instance, but not a .
So why did instance Functor IO ? Let's look at the class definition:
class Functor f where fmap :: (a -> b) -> fa -> fb
Now try substituting IO for f :
class Functor IO where fmap :: (a -> b) -> IO a -> IO b
IO at the end applies to type parameters, so it all works. Here we ran into problems if we tried to make a concrete type of type Int or A t instance of Functor .
source share