I'm trying to implement Functor
typeclass instance for a very trivial type Foo
:
data Foo a = Foo a
instance functorFoo :: Functor (Foo a) where
map fn (Foo a) = Foo (fn a)
Purescript gives me not-so-helpful error message:
Could not match kind
Type -> Type
with kind
Type
What does it mean? I'm not yet really familiar with the Kind-system.
But I'd still like to find out why does the first version not work. Like how does the Functor typeclass differ from e.g. Semigroup where the first version worked just fine.
Let's look at the definition of the Functor
type class:
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
It contains f a
and f b
types in the type signature of map
which clearly indicates that f
is of kind Type -> Type
(it "carries" another type). On the other hand Semigroup
clearly relates to plain types of kind Type
:
class Semigroup a where
append :: a -> a -> a
So Semigroup
is a class which can be defined for plain types like String
, Int
, List a
, Map k v
or even a function a -> b
(which can also be written as (->) a b
) but not type constructors which require another type like List
Map k
(->) a
(I have to use this notation here).
On the other hand Functor
class requires type constructors so you can have instances like Functor List
, Functor (Map k)
or Functor ((->) a)
.