> For the complete documentation index, see [llms.txt](https://harmeetsingh.gitbook.io/scala-type-system/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://harmeetsingh.gitbook.io/scala-type-system/phase-i/chapter-10-variance/non-variance.md).

# Invariance / Non-Variance

**Invariance** (also called **non-variance**) is the simplest form of variance. With invariance, **there is no subtype relationship between parameterized types**, even if their type arguments are related through inheritance (see Figure 10.1).

Recall the example from the previous section:

* `Lamborghini` is a subtype of `Car`.
* However, `Garage[Lamborghini]` is **not** a subtype of `Garage[Car]`.

In other words, the inheritance relationship between the type arguments is **not propagated** to the corresponding parameterized types. By default, every parameterized type in Scala is **invariant** unless a variance annotation (`+` or `-`) is explicitly specified.

Let's look at another example:

```scala
class Basket[T](fruitsOrVeg : T) {
	def addTheFuritOrVeg(fruitsOrVeg : T) : Unit = { … }
}

class Fruit
class Apple extends Fruit
class Orange extends Fruit
```

Here, the compiler constructs three different parameterized types:

```scala
new Basket[Fruit]
new Basket[Apple]
new Basket[Orange]
```

Although `Apple` and `Orange` are subclasses of `Fruit`, the corresponding parameterized types are completely unrelated. For example, the following assignments are **not** allowed:

```scala
val basket: Basket[Fruit] = new Basket[Apple](new Apple) 
// Compilation error
```

Similarly,

```scala
val basket: Basket[Apple] = new Basket[Fruit](new Fruit) // Compilation error
```

Since `Basket` is invariant, the compiler treats every constructed type as an independent type:

```scala
Basket[Fruit] 
Basket[Apple] 
Basket[Orange]
```

None of these types is considered a subtype or supertype of another, even though their type arguments are related by inheritance. Invariance provides the strongest type safety because the compiler never assumes a relationship between parameterized types unless it is explicitly declared.
