Why is this code correct
instance Functor IO where -- note that IO isn't parametrized, and it's correct
fmap f action = do
result <- action
return (f result)
but the following code has a compiler error?
class Print a where
print :: a -> String
data A t = A t
instance Print A where -- error: expecting one more argument to `A'
print a = "abc"
This is because the kinds don't match. Regular types have kind *
, while type constructors such as A
or IO
have kind * -> *
, indicating that they need a type parameter in order to return a type.
In the definition of the Print
class, the compiler infers that since a
is used as a plain type, it must have kind *
. However, Functor
works on type constructors of kind * -> *
:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Here, f
is not used as a plain type, but as a type constructor, so it's inferred kind is * -> *
. You can verify this with the :kind
command in GHCi:
> :kind Print
Print :: * -> Constraint
> :kind Functor
Functor :: (* -> *) -> Constraint
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With