Chapter 11: What are Kinds in Scala?
Last updated
Last updated
In chapter 1 we discussed values and with the help of Types we categories our values. We can say that Types are abstractions of values or in simple terms one-level above from values. Similarly, we have Kinds, Kinds are the abstraction of Types or we can say that, another level of values as you can see in the below diagram.
Now the question is, how can we figure out what is the Kind of any type? This is really the trickiest question, while we are creating any generics class or trait we define some abstract characters like A, T, and more, as we defined in chapter 6. If we want to check the Kind of any Type, below is the Scala REPL command.
In Scala REPL we can use :k or :kind to describe the Kind of any type.
In the first example, the output of String is A, A is similar to invariant as we defined in chapter 10 and it could be any Type. In the second example, we have the same output, because A could be any type, that's why Kinds are a more abstract version of Types.
Let’s take some other detailed examples.
In this example, we are using the additional flag -v which denotes to verbose mode output, or we can say that details output. In this detailed output, we are one special character * (asterisk).
Note: * (asterisk) symbol is only used by the compiler for explaining the types, we can't directly use * (asterisk) for type abstraction.
In Type-System * (asterisk) is the symbol that denotes to define types and its structure like String is the concrete type without any parameter, so it denotes via single * (asterisk). Let’s take some complex type as below:
In this example, List
is a parameterized constructor with co-variant types, in this case Kind of List
type defined by the symbolic way as * -(+)-> *
. As we know * (asterisk) denotes to types and (+) denotes co-variance, so we can say that List[+T]
or F[+A]
symbolic Kind value is * -(+)-> *
.
Note: To understand symbolic representation of Kinds, evaluate from Left to Right. This is for our understanding but I am not sure about the compiler evaluation.
Let's explore some more example:
In the case of multiple parameters type constructor like Map
or Either
, the Kind symbols are slightly different. The first * (asterisk) or left * (asterisk) denotes the outer type as we know like Map
or Either
and but the right side of them define the inner types like in the case of Map
key is invariant and value is co-variance so our output is * -> * -(+)-> *
and in the case of Either
both are co-variance our output is * -(+)-> * -(+)-> *
. On the basis of invariant or co-variant, the variance with symbols are decided.
These are the basics of Kinds and in the next chapter, we will explore Higher Kinded Types with example.