I understand the following kinds:
String :: *
[] :: * -> *
(->) :: * -> * -> *
(,) :: * -> * -> *
But what does this kind mean and what type might it represent?
? :: (* -> *) -> *
? :: (* -> *) -> *
means that if you give to ?
something of kind * -> *
, you'll get back a type (something of kind *
). Let's take a concrete example:
newtype IntContainer f = IC { getContainer :: f Int }
This is meant to contain Int
s. I can make IntContainer
s with lists, or sets, or anything I want (of kind * -> *
) as the underlying data structure. The thing is that f
isn't a type here - it needs to have another type applied to it before it is a type. So: IntContainer
needs to have something applied to it, which in turn needs a type applied to it.
ghci> :kind IntContainer
IntContainer :: (* -> *) -> *
I can make concrete types by applying things of kind * -> *
to IntContainer
:
ghci> ic1 = IC [1,2,3]
ic1 :: IntContainer [] -- [] :: * -> *
ghci> ic2 = IC (Data.Set.fromList [1,2,3])
ic2 :: IntContainer Set -- Set :: * -> *
ghci> ic3 = IC (Data.Sequence.fromList [1,2,3])
ic3 :: IntContainer Seq -- Seq :: * -> *