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