<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ covariant - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ covariant - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 17 May 2026 16:33:11 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/covariant/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to understand Scala variances by building restaurants ]]>
                </title>
                <description>
                    <![CDATA[ By Luca Florio I understand that type variance is not fundamental to writing Scala code. It's been more or less a year since I've been using Scala for my day-to-day job, and honestly, I've never had to worry much about it.  However, I think it is an ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/understand-scala-variances-building-restaurants/</link>
                <guid isPermaLink="false">66d45e4e052ad259f07e4ab3</guid>
                
                    <category>
                        <![CDATA[ covariant ]]>
                    </category>
                
                    <category>
                        <![CDATA[ contravariant ]]>
                    </category>
                
                    <category>
                        <![CDATA[ invariant ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Scala ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #variance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 24 Jul 2019 16:34:04 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9ca13e740569d1a4ca4d7c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Luca Florio</p>
<p>I understand that type variance is not fundamental to writing Scala code. It's been more or less a year since I've been using Scala for my day-to-day job, and honestly, I've never had to worry much about it. </p>
<p>However, I think it is an interesting "advanced" topic, so I started to study it. It is not easy to grasp it immediately, but with the right example, it might be a little bit easier to understand. Let me try using a food-based analogy...</p>
<h2 id="heading-what-is-type-variance">What is type variance?</h2>
<p>First of all, we have to define what type variance is. When you develop in an Object-Oriented language, you can define complex types. That means that a type may be parametrized using another type (component type). </p>
<p>Think of <code>List</code> for example. You cannot define a <code>List</code> without specifying which types will be inside the list. You do it by putting the type contained in the list inside square brackets: <code>List[String]</code>. When you define a complex type, you can specify how it will vary its subtype relationship according to the relation between the component type and its subtypes. </p>
<p>Ok, sounds like a mess... Let's get a little practical. </p>
<h2 id="heading-building-a-restaurant-empire">Building a restaurant empire</h2>
<p>Our goal is to build an empire of restaurants. We want generic and specialised restaurants. Every restaurant we will open needs a menu composed of different recipes, and a (possibly) starred chef. </p>
<p>The recipes can be composed of different kinds of food (fish, meat, white meat, vegetables, etc.), while the chef we hire has to be able to cook that kind of food. This is our model. Now it's coding time!</p>
<h2 id="heading-different-types-of-food">Different types of food</h2>
<p>For our food-based example, we start by defining the <code>Trait Food</code>, providing just the name of the food. </p>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">trait</span> <span class="hljs-title">Food</span> </span>{

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">name</span></span>: <span class="hljs-type">String</span>

}
</code></pre>
<p>Then we can create <code>Meat</code> and <code>Vegetable</code>, that are subclasses of <code>Food</code>. </p>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Meat</span>(<span class="hljs-params">val name: <span class="hljs-type">String</span></span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Food</span></span>
</code></pre>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Vegetable</span>(<span class="hljs-params">val name: <span class="hljs-type">String</span></span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Food</span></span>
</code></pre>
<p>In the end, we define a <code>WhiteMeat</code> class that is a subclass of <code>Meat</code>. </p>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WhiteMeat</span>(<span class="hljs-params">override val name: <span class="hljs-type">String</span></span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Meat</span>(<span class="hljs-params">name</span>)</span>
</code></pre>
<p>Sounds reasonable right? So we have this hierarchy of types.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/07/food_type_rel.png" alt="food subtype relationship" width="600" height="400" loading="lazy"></p>
<p>We can create some food instances of various type. They will be the ingredients of the recipes we are going to serve in our restaurants.</p>
<pre><code class="lang-scala"><span class="hljs-comment">// Food &lt;- Meat</span>
<span class="hljs-keyword">val</span> beef = <span class="hljs-keyword">new</span> <span class="hljs-type">Meat</span>(<span class="hljs-string">"beef"</span>)

<span class="hljs-comment">// Food &lt;- Meat &lt;- WhiteMeat</span>
<span class="hljs-keyword">val</span> chicken = <span class="hljs-keyword">new</span> <span class="hljs-type">WhiteMeat</span>(<span class="hljs-string">"chicken"</span>)
<span class="hljs-keyword">val</span> turkey = <span class="hljs-keyword">new</span> <span class="hljs-type">WhiteMeat</span>(<span class="hljs-string">"turkey"</span>)

<span class="hljs-comment">// Food &lt;- Vegetable</span>
<span class="hljs-keyword">val</span> carrot = <span class="hljs-keyword">new</span> <span class="hljs-type">Vegetable</span>(<span class="hljs-string">"carrot"</span>)
<span class="hljs-keyword">val</span> pumpkin = <span class="hljs-keyword">new</span> <span class="hljs-type">Vegetable</span>(<span class="hljs-string">"pumpkin"</span>)
</code></pre>
<h2 id="heading-recipe-a-covariant-type">Recipe, a covariant type</h2>
<p>Let's define the covariant type <code>Recipe</code>. It takes a component type that expresses the base food for the recipe - that is, a recipe based on meat, vegetable, etc.</p>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">trait</span> <span class="hljs-title">Recipe</span>[+<span class="hljs-type">A</span>] </span>{

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">name</span></span>: <span class="hljs-type">String</span>

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">ingredients</span></span>: <span class="hljs-type">List</span>[<span class="hljs-type">A</span>]

}
</code></pre>
<p>The <code>Recipe</code> has a name and a list of ingredients. The list of ingredients has the same type of <code>Recipe</code>. To express that the <code>Recipe</code> is covariant in its type <code>A</code>, we write it as <code>Recipe[+A]</code>. The generic recipe is based on every kind of food, the meat recipe is based on meat, and a white meat recipe has just white meat in its list of ingredients.</p>
<pre><code class="lang-scala"><span class="hljs-keyword">case</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GenericRecipe</span>(<span class="hljs-params">ingredients: <span class="hljs-type">List</span>[<span class="hljs-type">Food</span>]</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Recipe</span>[<span class="hljs-type">Food</span>] </span>{

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">name</span></span>: <span class="hljs-type">String</span> = <span class="hljs-string">s"Generic recipe based on <span class="hljs-subst">${ingredients.map(_.name)}</span>"</span>

}
</code></pre>
<pre><code class="lang-scala"><span class="hljs-keyword">case</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MeatRecipe</span>(<span class="hljs-params">ingredients: <span class="hljs-type">List</span>[<span class="hljs-type">Meat</span>]</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Recipe</span>[<span class="hljs-type">Meat</span>] </span>{

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">name</span></span>: <span class="hljs-type">String</span> = <span class="hljs-string">s"Meat recipe based on <span class="hljs-subst">${ingredients.map(_.name)}</span>"</span>

}
</code></pre>
<pre><code class="lang-scala"><span class="hljs-keyword">case</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WhiteMeatRecipe</span>(<span class="hljs-params">ingredients: <span class="hljs-type">List</span>[<span class="hljs-type">WhiteMeat</span>]</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Recipe</span>[<span class="hljs-type">WhiteMeat</span>] </span>{

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">name</span></span>: <span class="hljs-type">String</span> = <span class="hljs-string">s"Meat recipe based on <span class="hljs-subst">${ingredients.map(_.name)}</span>"</span>

}
</code></pre>
<p>A type is covariant if it follows the same relationship of subtypes of its component type. This means that <code>Recipe</code> follows the same subtype relationship of its component Food.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/07/recipe_type_rel-1.png" alt="recipe subtype relationship" width="600" height="400" loading="lazy"></p>
<p>Let's define some recipes that will be part of different menus.</p>
<pre><code class="lang-scala"><span class="hljs-comment">// Recipe[Food]: Based on Meat or Vegetable</span>
<span class="hljs-keyword">val</span> mixRecipe = <span class="hljs-keyword">new</span> <span class="hljs-type">GenericRecipe</span>(<span class="hljs-type">List</span>(chicken, carrot, beef, pumpkin))
<span class="hljs-comment">// Recipe[Food] &lt;- Recipe[Meat]: Based on any kind of Meat</span>
<span class="hljs-keyword">val</span> meatRecipe = <span class="hljs-keyword">new</span> <span class="hljs-type">MeatRecipe</span>(<span class="hljs-type">List</span>(beef, turkey))
<span class="hljs-comment">// Recipe[Food] &lt;- Recipe[Meat] &lt;- Recipe[WhiteMeat]: Based only on WhiteMeat</span>
<span class="hljs-keyword">val</span> whiteMeatRecipe = <span class="hljs-keyword">new</span> <span class="hljs-type">WhiteMeatRecipe</span>(<span class="hljs-type">List</span>(chicken, turkey))
</code></pre>
<h2 id="heading-chef-a-contravariant-type">Chef, a contravariant type</h2>
<p>We defined some recipes, but we need a chef to cook them. This gives us the chance to talk about contravariance. A type is contravariant if it follows an inverse relationship of subtypes of its component type. Let's define our complex type <code>Chef</code>, that is contravariant in the component type. The component type will be the food that the chef can cook. </p>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">trait</span> <span class="hljs-title">Chef</span>[-<span class="hljs-type">A</span>] </span>{

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">specialization</span></span>: <span class="hljs-type">String</span>

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cook</span></span>(recipe: <span class="hljs-type">Recipe</span>[<span class="hljs-type">A</span>]): <span class="hljs-type">String</span>
}
</code></pre>
<p>A <code>Chef</code> has a specialisation and a method to cook a recipe based on a specific food. We express that it is contravariant writing it as <code>Chef[-A]</code>. Now we can create a chef able to cook generic food, a chef able to cook meat and a chef specialised on white meat.</p>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GenericChef</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Chef</span>[<span class="hljs-type">Food</span>] </span>{

  <span class="hljs-keyword">val</span> specialization = <span class="hljs-string">"All food"</span>

  <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cook</span></span>(recipe: <span class="hljs-type">Recipe</span>[<span class="hljs-type">Food</span>]): <span class="hljs-type">String</span> = <span class="hljs-string">s"I made a <span class="hljs-subst">${recipe.name}</span>"</span>
}
</code></pre>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MeatChef</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Chef</span>[<span class="hljs-type">Meat</span>] </span>{

  <span class="hljs-keyword">val</span> specialization = <span class="hljs-string">"Meat"</span>

  <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cook</span></span>(recipe: <span class="hljs-type">Recipe</span>[<span class="hljs-type">Meat</span>]): <span class="hljs-type">String</span> = <span class="hljs-string">s"I made a <span class="hljs-subst">${recipe.name}</span>"</span>
}
</code></pre>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WhiteMeatChef</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Chef</span>[<span class="hljs-type">WhiteMeat</span>] </span>{

  <span class="hljs-keyword">override</span> <span class="hljs-keyword">val</span> specialization = <span class="hljs-string">"White meat"</span>

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cook</span></span>(recipe: <span class="hljs-type">Recipe</span>[<span class="hljs-type">WhiteMeat</span>]): <span class="hljs-type">String</span> = <span class="hljs-string">s"I made a <span class="hljs-subst">${recipe.name}</span>"</span>
}
</code></pre>
<p>Since <code>Chef</code> is contravariant, <code>Chef[Food]</code> is a subclass of <code>Chef[Meat]</code> that is a subclass of <code>Chef[WhiteMeat]</code>. This means that the relationship between subtypes is the inverse of its component type Food.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/07/chef_type_rel-1.png" alt="chef subtype relationship" width="600" height="400" loading="lazy"></p>
<p>Ok, we can now define different chef with various specialization to hire in our restaurants.</p>
<pre><code class="lang-scala"><span class="hljs-comment">// Chef[WhiteMeat]: Can cook only WhiteMeat</span>
<span class="hljs-keyword">val</span> giuseppe = <span class="hljs-keyword">new</span> <span class="hljs-type">WhiteMeatChef</span>
giuseppe.cook(whiteMeatRecipe)

<span class="hljs-comment">// Chef[WhiteMeat] &lt;- Chef[Meat]: Can cook only Meat</span>
<span class="hljs-keyword">val</span> alfredo = <span class="hljs-keyword">new</span> <span class="hljs-type">MeatChef</span>
alfredo.cook(meatRecipe)
alfredo.cook(whiteMeatRecipe)

<span class="hljs-comment">// Chef[WhiteMeat]&lt;- Chef[Meat] &lt;- Chef[Food]: Can cook any Food</span>
<span class="hljs-keyword">val</span> mario = <span class="hljs-keyword">new</span> <span class="hljs-type">GenericChef</span>
mario.cook(mixRecipe)
mario.cook(meatRecipe)
mario.cook(whiteMeatRecipe)
</code></pre>
<h2 id="heading-restaurant-where-things-come-together">Restaurant, where things come together</h2>
<p>We have recipes, we have chefs, now we need a restaurant where the chef can cook a menu of recipes.</p>
<pre><code class="lang-scala"><span class="hljs-class"><span class="hljs-keyword">trait</span> <span class="hljs-title">Restaurant</span>[<span class="hljs-type">A</span>] </span>{

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">menu</span></span>: <span class="hljs-type">List</span>[<span class="hljs-type">Recipe</span>[<span class="hljs-type">A</span>]]
  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">chef</span></span>: <span class="hljs-type">Chef</span>[<span class="hljs-type">A</span>]

  <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cookMenu</span></span>: <span class="hljs-type">List</span>[<span class="hljs-type">String</span>] = menu.map(chef.cook)
}
</code></pre>
<p>We are not interested in the subtype relationship between restaurants, so we can define it as invariant. An invariant type does not follow the relationship between the subtypes of the component type. In other words, <code>Restaurant[Food]</code> is not a subclass or superclass of <code>Restaurant[Meat]</code>. They are simply unrelated.
We will have a <code>GenericRestaurant</code>, where you can eat different type of food. The <code>MeatRestaurant</code> is specialised in meat-based dished and the <code>WhiteMeatRestaurant</code> is specialised only in dishes based on white meat. Every restaurant to be instantiated needs a menu, that is a list of recipes, and a chef able to cook the recipes in the menu. Here is where the subtype relationship of <code>Recipe</code> and <code>Chef</code> comes into play.</p>
<pre><code class="lang-scala"><span class="hljs-keyword">case</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GenericRestaurant</span>(<span class="hljs-params">menu: <span class="hljs-type">List</span>[<span class="hljs-type">Recipe</span>[<span class="hljs-type">Food</span>]], chef: <span class="hljs-type">Chef</span>[<span class="hljs-type">Food</span>]</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Restaurant</span>[<span class="hljs-type">Food</span>]</span>
</code></pre>
<pre><code class="lang-scala"><span class="hljs-keyword">case</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MeatRestaurant</span>(<span class="hljs-params">menu: <span class="hljs-type">List</span>[<span class="hljs-type">Recipe</span>[<span class="hljs-type">Meat</span>]], chef: <span class="hljs-type">Chef</span>[<span class="hljs-type">Meat</span>]</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Restaurant</span>[<span class="hljs-type">Meat</span>]</span>
</code></pre>
<pre><code class="lang-scala"><span class="hljs-keyword">case</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WhiteMeatRestaurant</span>(<span class="hljs-params">menu: <span class="hljs-type">List</span>[<span class="hljs-type">Recipe</span>[<span class="hljs-type">WhiteMeat</span>]], chef: <span class="hljs-type">Chef</span>[<span class="hljs-type">WhiteMeat</span>]</span>) <span class="hljs-keyword">extends</span> <span class="hljs-title">Restaurant</span>[<span class="hljs-type">WhiteMeat</span>]</span>
</code></pre>
<p>Let's start defining some generic restaurants. In a generic restaurant, the menu is composed of recipes of various type of food. Since <code>Recipe</code> is covariant, a <code>GenericRecipe</code> is a superclass of <code>MeatRecipe</code> and <code>WhiteMeatRecipe</code>, so I can pass them to my <code>GenericRestaurant</code> instance. The thing is different for the chef. If the Restaurant requires a chef that can cook generic food, I cannot put in it a chef able to cook only a specific one. The class <code>Chef</code> is covariant, so <code>GenericChef</code> is a subclass of <code>MeatChef</code> that is a subclass of <code>WhiteMeatChef</code>. This implies that I cannot pass to my instance anything different from <code>GenericChef</code>.</p>
<pre><code class="lang-scala"><span class="hljs-keyword">val</span> allFood = <span class="hljs-keyword">new</span> <span class="hljs-type">GenericRestaurant</span>(<span class="hljs-type">List</span>(mixRecipe), mario)
<span class="hljs-keyword">val</span> foodParadise = <span class="hljs-keyword">new</span> <span class="hljs-type">GenericRestaurant</span>(<span class="hljs-type">List</span>(meatRecipe), mario)
<span class="hljs-keyword">val</span> superFood = <span class="hljs-keyword">new</span> <span class="hljs-type">GenericRestaurant</span>(<span class="hljs-type">List</span>(whiteMeatRecipe), mario)
</code></pre>
<p>The same goes for <code>MeatRestaurant</code> and <code>WhiteMeatRestaurant</code>. I can pass to the instance only a menu composed of more specific recipes then the required one, but chefs that can cook food more generic than the required one.</p>
<pre><code class="lang-scala"><span class="hljs-keyword">val</span> meat4All = <span class="hljs-keyword">new</span> <span class="hljs-type">MeatRestaurant</span>(<span class="hljs-type">List</span>(meatRecipe), alfredo)
<span class="hljs-keyword">val</span> meetMyMeat = <span class="hljs-keyword">new</span> <span class="hljs-type">MeatRestaurant</span>(<span class="hljs-type">List</span>(whiteMeatRecipe), mario)
</code></pre>
<pre><code class="lang-scala"><span class="hljs-keyword">val</span> notOnlyChicken = <span class="hljs-keyword">new</span> <span class="hljs-type">WhiteMeatRestaurant</span>(<span class="hljs-type">List</span>(whiteMeatRecipe), giuseppe)
<span class="hljs-keyword">val</span> whiteIsGood = <span class="hljs-keyword">new</span> <span class="hljs-type">WhiteMeatRestaurant</span>(<span class="hljs-type">List</span>(whiteMeatRecipe), alfredo)
<span class="hljs-keyword">val</span> wingsLovers = <span class="hljs-keyword">new</span> <span class="hljs-type">WhiteMeatRestaurant</span>(<span class="hljs-type">List</span>(whiteMeatRecipe), mario)
</code></pre>
<p>That's it, our empire of restaurants is ready to make tons of money!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Ok guys, in this story I did my best to explain type variances in Scala. It is an advanced topic, but it is worth to know just out of curiosity. I hope that the restaurant example can be of help to make it more understandable. If something is not clear, or if I wrote something wrong (I'm still learning!) don't hesitate to leave a comment!</p>
<p>See you! ?</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
