# Chapter 11: What are Kinds in Scala?

## **Kinds?**

In [chapter 1](https://harmeetsingh.gitbook.io/scala-type-system/phase-i/chapter-1-what-are-the-types) 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.

![Types Abstraction and Concretization](https://1204724341-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Le1KKAral0xiRzMJGwM%2F-M7T4cNcfp6Cxf0s4fiu%2F-M7T5PVhK0TciXaMrDEn%2Ftypes%20and%20values%20scope%20\(1\).png?alt=media\&token=386beeb9-bf47-487f-8d24-313dfb981718)

**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.**](https://harmeetsingh.gitbook.io/scala-type-system/phase-i/chapter-6-parameterized-types) If we want to check the **Kind** of any  **Type**, below is the Scala REPL command.

```
scala> :k String
String's kind is A

scala> :k Int
String's kind is A
```

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](https://harmeetsingh.gitbook.io/scala-type-system/phase-i/chapter-10-variance) 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.**&#x20;

```
scala> :k -v String
String's kind is A
*
This is a proper type.
```

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:

```
scala> :k -v List
List's kind is F[+A]
* -(+)-> *
This is a type constructor: a 1st-order-kinded type.
```

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:**

```
scala> :k -v Map
Map's kind is F[A1,+A2]
* -> * -(+)-> *
This is a type constructor: a 1st-order-kinded type.

scala> :k -v Either
Either's kind is F[+A1,+A2]
* -(+)-> * -(+)-> *
This is a type constructor: a 1st-order-kinded type.
```

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. &#x20;

These are the basics of **Kinds** and in the next chapter, we will explore **Higher Kinded Types** with example.
