问题
Why do both of these have the same kind?
ghci> :k [Int]
[Int] :: *
ghci> :k [Int -> Int]
[Int -> Int] :: *
EDIT per @Gabriel Gonzalez's helpful comment.
I don't understand kinds
well, so I don't have a good basis for expecting the above types to vary in kind
.
回答1:
Well, let's check.
Int :: *
[] :: * -> *
So when you apply the Int
type to the []
type constructor:
[] Int :: *
Which is just another (legal) way of writing
[Int] :: *
Ok, that one follows pretty easily.
Int :: *
(->) :: * -> * -> *
[] :: * -> *
(->) Int :: * -> *
(->) Int Int :: *
Which is the same as
Int -> Int :: *
and therefore, by the same reasoning as above,
[Int -> Int] :: *
But here's a secret.. Take a closer look at the kind of []
.
[] :: * -> *
That means that it's a compile error to put any type inside a list that isn't of kind *
. And when you do provide it with something of kind *
, the result will always have kind *
.
Your confusion comes from not keeping levels separate. Many, many different types have the same kind. After all, kind *
more or less means "this type can have values". (There are some minor exceptions, but they're low-level internals things that you have to work quite hard to see.) If you can have a value of a type, it's a very good bet that the type has kind *
.
回答2:
The kind *
stands for a concrete type. One way to think of a concrete type is that it doesn't take any type parameters. All of these are concrete types:
Int
Int -> Int
The type []
has kind * -> *
-- it takes a concrete type and returns a concrete type.
Therefore both of these are concrete types (i.e. has kind *
):
[ Int ]
[ Int -> Int ]
回答3:
In short, The kind *
means a type. Any value , even function (functions are value) Int
, [Int]
, Int -> [Int]
have a kind of *
.
Types like Maybe are in fact a type constructor, they construct a new type from an existing type.
Maybe Int
is a new type, Maybe Float
another one etc ... wheresas.
So Maybe
is a super function, which takes a type (for example Int
) and returns an new one Maybe Int
.
This is what * -> *
means : take a type and return a new type. So Maybe
is not a type itself, you can't use it by itself in a type signature, you need Maybe a
, which is a type.
In the same way a 2-uple (,)
, takes 2 types a
and b
and create a new one : (a, b)
. It's kind is
* -> * -> *
etc ...
来源:https://stackoverflow.com/questions/24983642/same-kinds-for-list-of-int-compared-to-list-of-int-int