{"id":572,"date":"2015-08-07T07:44:11","date_gmt":"2015-08-07T07:44:11","guid":{"rendered":"http:\/\/blog.stratio.com\/?p=572"},"modified":"2023-09-20T13:37:59","modified_gmt":"2023-09-20T13:37:59","slug":"variance-in-scala-luke-he-is-your-father-too","status":"publish","type":"post","link":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/","title":{"rendered":"Variance in Scala (\u201cLuke, he is your father too\u201d)"},"content":{"rendered":"<p style=\"text-align: justify;\">When working with&nbsp;<strong>Big Data<\/strong>, sometimes it\u2019s useful to remember that powerful products wouldn&#8217;t work properly without the tools that build them. It\u2019s possible to start programming in&nbsp;<strong>Scala<\/strong>&nbsp;with a few case classes and a bunch of for-comprehensions, but those are only little scratches in a huge ice surface like Scala is. It may not be enough to make your code clean and comprehensible. &nbsp;I\u2019ve been developing with this programming language for almost 4 years, and every day I discover a new feature that surprises me. That acknowledgement, in the end, is the main reason to keep digging deeper into Scala.<!--more--><\/p>\n<p style=\"text-align: justify;\">For instance, working with generics can be sometimes really messy, especially when we want to play a little bit with&nbsp;<strong>inheritance<\/strong>&nbsp;(which turns out to be very common).<\/p>\n<p style=\"text-align: justify;\">It&#8217;s very usual to clash with&nbsp;<strong>variance<\/strong>&nbsp;issues in that case, but not as usual as getting a clear idea about what it really implies.<\/p>\n<p style=\"text-align: justify;\">Just to set the tone, we will propose a simple example.<\/p>\n<h2>Invariance<strong>&nbsp;<\/strong><\/h2>\n<p>Let&#8217;s suppose we&#8217;re defining the behavior of some servers\u2019 connection handler&#8230;<\/p>\n<pre class=\"lang:default decode:true \">case class ConnectionHandler[C](connections: List[C])<\/pre>\n<p>&#8230;and connection&#8217;s definition (we could have two types of connections: user and system connections):<\/p>\n<pre class=\"lang:default decode:true \">trait Connection\n\nclass UserConnection extends Connection\n\nclass SystemConnection extends Connection<\/pre>\n<p style=\"text-align: justify;\">If we want to list all connections given a connection handler, we probably need a logger to print them all and a function for using this logger for each connection:<\/p>\n<pre class=\"lang:default decode:true\">case class FunctionalLogger(traces: Seq[String]= Seq()) {\n\n  def print(trace: String): FunctionalLogger =\n    this.copy(traces :+ trace)\n\n}<\/pre>\n<p style=\"text-align: justify;\">Why this freak logger? It\u2019s quite common to invoke \u2018println\u2019 and similar methods in Java, and it can be done as well in Scala, but functional purists don\u2019t support this idea.<\/p>\n<p style=\"text-align: justify;\">Let\u2019s focus for a moment on the main ideas of functional programming:<\/p>\n<ul style=\"text-align: justify;\">\n<li>a function may have one (or more) input parameters and an only parameter type<\/li>\n<li>same input will always generate the same output.<\/li>\n<li>instances shall not be modified: state mutation is provided by a new instance of same type.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Having this in mind, what we have provided here is a pretty functional logger that doesn&#8217;t perform IO operations that would break the pure nature of functions.<\/p>\n<p style=\"text-align: justify;\">If we continue implementing our method&#8230;<\/p>\n<pre class=\"lang:default decode:true\">def listConnections(\n  handler: ConnectionHandler[Connection])(\n  logger: FunctionalLogger): FunctionalLogger = {\n\n&nbsp; (logger \/: handler.connections)(\n&nbsp; &nbsp; (logger,connection) =&gt; logger.print(connection.toString))\n\n}<\/pre>\n<p style=\"text-align: justify;\">&#8230;what we have is a method that performs a&nbsp;<code>foldLeft<\/code>&nbsp;over the logger, printing on it all connections that belong to given handler.<\/p>\n<p style=\"text-align: justify;\">Easy peasy, but what happens if we try to list the connections of the following connection handler?<\/p>\n<pre class=\"lang:default decode:true\">val handler: ConnectionHandler[UserConnection] = \n  ConnectionHandler(List(new UserConnection))\n\nlistConnections(handler)(FunctionalLogger())<\/pre>\n<p>The compiler will complain with the following \u201cwookie-incomprehensible\u201d error:<\/p>\n<pre class=\"lang:default decode:true\">&lt;console&gt;:19: error: type mismatch;\n\nfound &nbsp;&nbsp;: ConnectionHandler[UserConnection]\n\nrequired: ConnectionHandler[Connection]\n\nNote: UserConnection &lt;: Connection, but class ConnectionHandler is invariant in type C.\n\nYou may wish to define C as +C instead. (SLS 4.5)<\/pre>\n<p style=\"text-align: justify;\">If we translate this into human, it means that&nbsp;<code>UserConnection<\/code>&nbsp;is a subtype of&nbsp;<code>Connection<\/code>, but we cannot make this condition extensive to connection handler (<code>ConnectionHandler[UserConnection]&lt;:ConnectionHandler[Connection]<\/code>). How do we fix this?<\/p>\n<h2>Covariance<\/h2>\n<p>In order to make this inheritance relation flexible, we have to slightly modify the signature of&nbsp;<code>ConnectionHandler<\/code>:<\/p>\n<pre class=\"lang:default decode:true\">case class ConnectionHandler[+C](connections: List[C])<\/pre>\n<p>Note the plus sign: it means that any&nbsp;<code>ConnectionHandler[T]<\/code>&nbsp;will be a subtype of&nbsp;<code>ConnectionHandler[C]<\/code>&nbsp;if&nbsp;<code>T<\/code>&nbsp;is a subtype of&nbsp;<code>C<\/code>.<\/p>\n<p>Now&nbsp;<code>ConnectionHandler<\/code>&nbsp;is covariant in&nbsp;<code>C<\/code>&nbsp;and the code that wasn\u2019t working before should work now. We can prove it by the following simple line<\/p>\n<pre class=\"lang:default decode:true\">implicitly[&lt;:&lt;[ConnectionHandler[UserConnection],ConnectionHandler[Connection]]]<\/pre>\n<p>which tries to find an implicit evidence of first type is a subtype of the second.<\/p>\n<p>If we tried this with unrelated types like&nbsp;<code>Int<\/code>&nbsp;and&nbsp;<code>String<\/code>\u2026.<\/p>\n<pre class=\"lang:default decode:true \">implicitly[&lt;:&lt;[ConnectionHandler[String],ConnectionHandler[Int]]]<\/pre>\n<p>we would get a compilation error like:<\/p>\n<pre class=\"lang:default decode:true \">Error: Cannot prove thatConnectionHandler[String] &lt;:&lt;ConnectionHandler[Int].\n\nimplicitly[&lt;:&lt;[ConnectionHandler[String],ConnectionHandler[Int]]]\n\n^<\/pre>\n<h2>Contravariance<\/h2>\n<p style=\"text-align: justify;\">On the other hand, we could define a contravariant class&nbsp;<code>C[_]<\/code>&nbsp;in its parameter type using the minus sign, just in front of parameter type.<\/p>\n<p style=\"text-align: justify;\">This means, given two types&nbsp;<code>T<\/code>&nbsp;and&nbsp;<code>V<\/code>, if&nbsp;<code>T<\/code>&nbsp;is a supertype of&nbsp;<code>V<\/code>, then&nbsp;<code>C[T]<\/code>&nbsp;will be subtype of&nbsp;<code>C[V]<\/code>.<\/p>\n<p style=\"text-align: justify;\">Confusing? The real question here is, who in his right mind would need this? Maybe the following example is self-explanatory.<\/p>\n<p style=\"text-align: justify;\">Without going too far&#8230;Scala\u2019s functions are defined like:<\/p>\n<pre class=\"lang:default decode:true\">trait Function1[-Parameter,+Result] extends AnyRef<\/pre>\n<p>Not so inspiring so far, but think about the following class hierarchy and the following higher-order function:<\/p>\n<pre class=\"lang:default decode:true\">trait Vehicle { def wheels: Int }\n\nclass Car extends Vehicle { val wheels = 4 }\n\nclass Truck extends Car { override val wheels = 6 }\n\nval myFunction: Car =&gt; Any = ???<\/pre>\n<p>Remember that&nbsp;<code>myFunction<\/code>&nbsp;signature is syntactic sugar for<\/p>\n<pre class=\"lang:default decode:true \">val myFunction: Function1[Car,Any] = ???<\/pre>\n<p>So if you had a&nbsp;<code>Truck<\/code>, that is a subtype of&nbsp;<code>Car<\/code>, you couldn&#8217;t define your function as follows:<\/p>\n<pre class=\"lang:default decode:true \">val myFunction: Function1[Car,Any] = \n  (t: Truck) =&gt; println(t.wheels)<\/pre>\n<p style=\"text-align: justify;\">because it is contravariant in&nbsp;<code>Parameter<\/code>,&nbsp;<code>Function1<\/code>&nbsp;expects a supertype of&nbsp;<code>Car<\/code>, that&#8217;s why you could define your function using&nbsp;<code>Vehicle<\/code>&nbsp;instead:<\/p>\n<pre class=\"lang:default decode:true \">val myFunction: Function1[Car,Any] = (t: Vehicle) =&gt; println(t.wheels)<\/pre>\n<p style=\"text-align: justify;\">And also don&#8217;t forget that covariance in type&nbsp;<code>Result<\/code>&nbsp;is being satisfied due to&nbsp;<code>Unit<\/code>&nbsp;(the result type of&nbsp;<code>println<\/code>) is a subtype of&nbsp;<code>Any<\/code>. A little bit tricky in the end, but essentially, that was the main idea \ud83d\ude42<\/p>\n<p style=\"text-align: justify;\"><strong>\u201c<i>May the functional programming be with you<\/i>\u201d&#8230;<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When working with\u00a0Big Data, sometimes it\u2019s useful to remember that powerful products wouldn&#8217;t work properly without the tools that build them. <\/p>\n","protected":false},"author":1,"featured_media":632,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[686],"tags":[],"ppma_author":[795],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v22.9 (Yoast SEO v22.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Variance in Scala (\u201cLuke, he is your father too\u201d) - Stratio Blog<\/title>\n<meta name=\"description\" content=\"When programming in Scala it&#039;s usual to clash with variance issues, but it&#039;s not always easy to know what it implies: invariance, covariance, contravariance\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Variance in Scala (\u201cLuke, he is your father too\u201d)\" \/>\n<meta property=\"og:description\" content=\"When programming in Scala it&#039;s usual to clash with variance issues, but it&#039;s not always easy to know what it implies: invariance, covariance, contravariance\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/\" \/>\n<meta property=\"og:site_name\" content=\"Stratio\" \/>\n<meta property=\"article:published_time\" content=\"2015-08-07T07:44:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-20T13:37:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png\" \/>\n\t<meta property=\"og:image:width\" content=\"730\" \/>\n\t<meta property=\"og:image:height\" content=\"312\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Stratio\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@stratiobd\" \/>\n<meta name=\"twitter:site\" content=\"@stratiobd\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Stratio\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/\"},\"author\":{\"name\":\"Stratio\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/d0377b199cd052b17e15c9ba44c45ab7\"},\"headline\":\"Variance in Scala (\u201cLuke, he is your father too\u201d)\",\"datePublished\":\"2015-08-07T07:44:11+00:00\",\"dateModified\":\"2023-09-20T13:37:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/\"},\"wordCount\":755,\"publisher\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png\",\"articleSection\":[\"Product\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/\",\"url\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/\",\"name\":\"Variance in Scala (\u201cLuke, he is your father too\u201d) - Stratio Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png\",\"datePublished\":\"2015-08-07T07:44:11+00:00\",\"dateModified\":\"2023-09-20T13:37:59+00:00\",\"description\":\"When programming in Scala it's usual to clash with variance issues, but it's not always easy to know what it implies: invariance, covariance, contravariance\",\"breadcrumb\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#primaryimage\",\"url\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png\",\"contentUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png\",\"width\":730,\"height\":312},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.stratio.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Variance in Scala (\u201cLuke, he is your father too\u201d)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#website\",\"url\":\"https:\/\/www.stratio.com\/blog\/\",\"name\":\"Stratio Blog\",\"description\":\"Corporate blog\",\"publisher\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.stratio.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\",\"name\":\"Stratio\",\"url\":\"https:\/\/www.stratio.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png\",\"contentUrl\":\"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png\",\"width\":260,\"height\":55,\"caption\":\"Stratio\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/stratiobd\",\"https:\/\/es.linkedin.com\/company\/stratiobd\",\"https:\/\/www.youtube.com\/c\/StratioBD\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/d0377b199cd052b17e15c9ba44c45ab7\",\"name\":\"Stratio\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/image\/bb38888f58c2bb664646155f78ae6ccc\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g\",\"caption\":\"Stratio\"},\"description\":\"Stratio guides businesses on their journey through complete #DigitalTransformation with #BigData and #AI. Stratio works worldwide for large companies and multinationals in the sectors of banking, insurance, healthcare, telco, retail, energy and media.\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Variance in Scala (\u201cLuke, he is your father too\u201d) - Stratio Blog","description":"When programming in Scala it's usual to clash with variance issues, but it's not always easy to know what it implies: invariance, covariance, contravariance","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/","og_locale":"en_US","og_type":"article","og_title":"Variance in Scala (\u201cLuke, he is your father too\u201d)","og_description":"When programming in Scala it's usual to clash with variance issues, but it's not always easy to know what it implies: invariance, covariance, contravariance","og_url":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/","og_site_name":"Stratio","article_published_time":"2015-08-07T07:44:11+00:00","article_modified_time":"2023-09-20T13:37:59+00:00","og_image":[{"width":730,"height":312,"url":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png","type":"image\/png"}],"author":"Stratio","twitter_card":"summary_large_image","twitter_creator":"@stratiobd","twitter_site":"@stratiobd","twitter_misc":{"Written by":"Stratio","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#article","isPartOf":{"@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/"},"author":{"name":"Stratio","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/d0377b199cd052b17e15c9ba44c45ab7"},"headline":"Variance in Scala (\u201cLuke, he is your father too\u201d)","datePublished":"2015-08-07T07:44:11+00:00","dateModified":"2023-09-20T13:37:59+00:00","mainEntityOfPage":{"@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/"},"wordCount":755,"publisher":{"@id":"https:\/\/www.stratio.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#primaryimage"},"thumbnailUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png","articleSection":["Product"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/","url":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/","name":"Variance in Scala (\u201cLuke, he is your father too\u201d) - Stratio Blog","isPartOf":{"@id":"https:\/\/www.stratio.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#primaryimage"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#primaryimage"},"thumbnailUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png","datePublished":"2015-08-07T07:44:11+00:00","dateModified":"2023-09-20T13:37:59+00:00","description":"When programming in Scala it's usual to clash with variance issues, but it's not always easy to know what it implies: invariance, covariance, contravariance","breadcrumb":{"@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#primaryimage","url":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png","contentUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2015\/08\/ScalaVarianceInheritance.png","width":730,"height":312},{"@type":"BreadcrumbList","@id":"https:\/\/www.stratio.com\/blog\/variance-in-scala-luke-he-is-your-father-too\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.stratio.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Variance in Scala (\u201cLuke, he is your father too\u201d)"}]},{"@type":"WebSite","@id":"https:\/\/www.stratio.com\/blog\/#website","url":"https:\/\/www.stratio.com\/blog\/","name":"Stratio Blog","description":"Corporate blog","publisher":{"@id":"https:\/\/www.stratio.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.stratio.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.stratio.com\/blog\/#organization","name":"Stratio","url":"https:\/\/www.stratio.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png","contentUrl":"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png","width":260,"height":55,"caption":"Stratio"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/stratiobd","https:\/\/es.linkedin.com\/company\/stratiobd","https:\/\/www.youtube.com\/c\/StratioBD"]},{"@type":"Person","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/d0377b199cd052b17e15c9ba44c45ab7","name":"Stratio","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/image\/bb38888f58c2bb664646155f78ae6ccc","url":"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g","caption":"Stratio"},"description":"Stratio guides businesses on their journey through complete #DigitalTransformation with #BigData and #AI. Stratio works worldwide for large companies and multinationals in the sectors of banking, insurance, healthcare, telco, retail, energy and media."}]}},"authors":[{"term_id":795,"user_id":1,"is_guest":0,"slug":"stratioadmin","display_name":"Stratio","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/e3387ad00609f34a56d6796400eb8191?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/572"}],"collection":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/comments?post=572"}],"version-history":[{"count":9,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/572\/revisions"}],"predecessor-version":[{"id":15683,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/572\/revisions\/15683"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/media\/632"}],"wp:attachment":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/media?parent=572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/categories?post=572"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/tags?post=572"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}