Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I make an instance with this unparameterized type?

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"
like image 436
Nelson Tatius Avatar asked Oct 25 '12 21:10

Nelson Tatius


1 Answers

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 
like image 137
hammar Avatar answered Oct 06 '22 10:10

hammar