From cd7dfea7a1cd6ad6a308797549c90ebe73b74a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82?= Date: Fri, 2 Dec 2016 21:05:03 +0100 Subject: [PATCH 1/2] Add covariant type in contravariant position article --- _config.yml | 2 +- ...016-12-04-covariant_contravariant.markdown | 60 +++++++++++++++++++ _site/feed.xml | 49 +++++++++++++-- _site/index.html | 9 +++ 4 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 _posts/2016-12-04-covariant_contravariant.markdown diff --git a/_config.yml b/_config.yml index 67c69eb..b1962b5 100644 --- a/_config.yml +++ b/_config.yml @@ -17,7 +17,7 @@ title: Main description: > # this means to ignore newlines until "baseurl:" Programmer and programming related content. baseurl: "" # the subpath of your site, e.g. /blog -url: "http://pgebal.github.io" # the base hostname & protocol for your site, e.g. http://example.com +url: "http://pawelgebal.com" twitter_username: pawelwgebal github_username: pgebal disqus: diff --git a/_posts/2016-12-04-covariant_contravariant.markdown b/_posts/2016-12-04-covariant_contravariant.markdown new file mode 100644 index 0000000..433d953 --- /dev/null +++ b/_posts/2016-12-04-covariant_contravariant.markdown @@ -0,0 +1,60 @@ +--- +layout: post +title: "A short one: Covariant type in a contravariant position" +date: 2016-12-04 12:00:00 +0100 +categories: scala update +tags: scala functional-programming +excerpt: It will never happen to you after reading this. +--- +There is an exercise in the great [Functional Programming in Scala][functional-programming-in-scala-affiliate-link] book, that requires you to +implement **Option** trait and it's **getOrElse** method. +My first try on it was: +{: .text-justify} +{% highlight scala %} +sealed trait Option[+A] { + + def getOrElse(default: => A): A = this match { + case Some(a) => a + case None => default + } +} + +case class Some[+A](value: A) extends Option[A] +case object None extends Option[Nothing] +{% endhighlight %} + +IntelliJ Idea was quick to tell me that it's not a right solution because: +{% highlight scala %} +Covariant type A in contravariant position in type A of value default. +{% endhighlight %} + +I looked to the book and noticed that they suggest to use the following definition for **getOrElse**: +{% highlight scala %} +def getOrElse[B >: A](default: => B): B = this match { + case Some(a) => a + case None => default +} +{% endhighlight %} + +At first I didn't know why the solution required to use type parameter **B** that is a supertype of **A**. +It turned out to be quite simple. +Notice that **A** is a covariant type parameter for **Option**. +That means for every **A** that is a subtype of **B**, **Option[A]** is a subtype of **Option[B]**. +So whenever we use expression of type **Option[A]**, we have to be able to substitute it with expression of type **Option[B]**. +Study this: +{: .text-justify} + +{% highlight scala %} +class B +class A extends B + +val b: Option[B] = None +val a: Option[A] = None + +val default: B = b.getOrElse(new B) +{% endhighlight %} +Note that in the last line we could use **a** instead of **b** and the code would stay valid. That's thanks to [B >: A] bound in **getOrElse** method definition. If it wasn't for that **a.getOrElse** would not accept an argument of type **B**. Keep this example in mind and embrace [Liskov substitution principle][liskov-substitution-principle] when implementing your own classes with type parameters. +{: .text-justify} + +[functional-programming-in-scala-affiliate-link]: https://www.amazon.com/gp/product/1617290653/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1617290653&linkCode=as2&tag=pawelgebal-20&linkId=f3ec949cadbc0ff936a5aae1dcc51c0a +[liskov-substitution-principle]:https://en.wikipedia.org/wiki/Liskov_substitution_principle diff --git a/_site/feed.xml b/_site/feed.xml index 891b3fe..1883470 100644 --- a/_site/feed.xml +++ b/_site/feed.xml @@ -1,11 +1,52 @@ -Jekyll2016-11-27T13:03:30+01:00http://localhost:4000//MainProgrammer and programming related content. -Type class pattern2016-11-27T11:00:00+01:002016-11-27T11:00:00+01:00http://localhost:4000/scala/update/2016/11/27/type-classes<p>To get the most out of this article I encourage you to put the pieces of code you find here into a scala worksheet and play with it.</p> +Jekyll2016-12-02T21:24:24+01:00http://localhost:4000//MainProgrammer and programming related content. +A short one: Covariant type in a contravariant position2016-12-02T11:00:00+01:002016-12-02T11:00:00+01:00http://localhost:4000/scala/update/2016/12/02/covariant_contravariant<p class="text-justify">There is an exercise in the great <a href="https://www.amazon.com/gp/product/1617290653/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1617290653&amp;linkCode=as2&amp;tag=pawelgebal-20&amp;linkId=f3ec949cadbc0ff936a5aae1dcc51c0a">Functional Programming in Scala</a> book, that requires you to +implement <strong>Option</strong> trait and it’s <strong>getOrElse</strong> method. +My first try on it was:</p> + +<figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="k">sealed</span> <span class="k">trait</span> <span class="nc">Option</span><span class="o">[</span><span class="kt">+A</span><span class="o">]</span> <span class="o">{</span> + + <span class="k">def</span> <span class="n">getOrElse</span><span class="o">(</span><span class="n">default</span><span class="k">:</span> <span class="o">=&gt;</span> <span class="n">A</span><span class="o">)</span><span class="k">:</span> <span class="kt">A</span> <span class="o">=</span> <span class="k">this</span> <span class="k">match</span> <span class="o">{</span> + <span class="k">case</span> <span class="nc">Some</span><span class="o">(</span><span class="n">a</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">a</span> + <span class="k">case</span> <span class="nc">None</span> <span class="k">=&gt;</span> <span class="n">default</span> + <span class="o">}</span> +<span class="o">}</span> + +<span class="k">case</span> <span class="k">class</span> <span class="nc">Some</span><span class="o">[</span><span class="kt">+A</span><span class="o">](</span><span class="n">value</span><span class="k">:</span> <span class="kt">A</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Option</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> +<span class="k">case</span> <span class="k">object</span> <span class="nc">None</span> <span class="k">extends</span> <span class="nc">Option</span><span class="o">[</span><span class="kt">Nothing</span><span class="o">]</span></code></pre></figure> + +<p>IntelliJ Idea was quick to tell me that it’s not a right solution because:</p> + +<figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="nc">Covariant</span> <span class="k">type</span> <span class="kt">A</span> <span class="kt">in</span> <span class="kt">contravariant</span> <span class="kt">position</span> <span class="kt">in</span> <span class="k">type</span> <span class="kt">A</span> <span class="kt">of</span> <span class="kt">value</span> <span class="kt">default.</span></code></pre></figure> + +<p>I looked to the book and noticed that they suggest to use the following definition for <strong>getOrElse</strong>:</p> + +<figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">getOrElse</span><span class="o">[</span><span class="kt">B</span> <span class="k">&gt;:</span> <span class="kt">A</span><span class="o">](</span><span class="n">default</span><span class="k">:</span> <span class="o">=&gt;</span> <span class="n">B</span><span class="o">)</span><span class="k">:</span> <span class="kt">B</span> <span class="o">=</span> <span class="k">this</span> <span class="k">match</span> <span class="o">{</span> + <span class="k">case</span> <span class="nc">Some</span><span class="o">(</span><span class="n">a</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">a</span> + <span class="k">case</span> <span class="nc">None</span> <span class="k">=&gt;</span> <span class="n">default</span> +<span class="o">}</span></code></pre></figure> + +<p class="text-justify">At first I didn’t know why the solution required to use type parameter <strong>B</strong> that is a supertype of <strong>A</strong>. +It turned out to be quite simple. +Notice that <strong>A</strong> is a covariant type parameter for <strong>Option</strong>. +That means for every <strong>A</strong> that is a subtype of <strong>B</strong>, <strong>Option[A]</strong> is a subtype of <strong>Option[B]</strong>. +So whenever we use expression of type <strong>Option[A]</strong>, we have to be able to substitute it with expression of type <strong>Option[B]</strong>. +Study this:</p> + +<figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="k">class</span> <span class="nc">B</span> +<span class="k">class</span> <span class="nc">A</span> <span class="k">extends</span> <span class="n">B</span> + +<span class="k">val</span> <span class="n">b</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">B</span><span class="o">]</span> <span class="k">=</span> <span class="nc">None</span> +<span class="k">val</span> <span class="n">a</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="nc">None</span> + +<span class="k">val</span> <span class="n">default</span><span class="k">:</span> <span class="kt">B</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">getOrElse</span><span class="o">(</span><span class="k">new</span> <span class="n">B</span><span class="o">)</span></code></pre></figure> + +<p class="text-justify">Note that in the last line we could use <strong>a</strong> instead of <strong>b</strong> and the code would stay valid. That’s thanks to <nobr><b>[B &gt;: A]</b></nobr> bound in <strong>getOrElse</strong> method definition. If it wasn’t for that <strong>a.getOrElse</strong> would not accept an argument of type <strong>B</strong>. Keep this example in mind and embrace <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov substitution principle</a> when implementing your own classes with type parameters.</p>It will never happen to you after reading this.Type class pattern2016-11-27T11:00:00+01:002016-11-27T11:00:00+01:00http://localhost:4000/scala/update/2016/11/27/type-classes<p>To get the most out of this article I encourage you to put the pieces of code you find here into a scala worksheet and play with it.</p> <p>Let’s have a class that we want to serialize to JSON:</p> <figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="k">case</span> <span class="k">class</span> <span class="nc">Color</span><span class="o">(</span><span class="n">name</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="n">red</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span> <span class="n">green</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span> <span class="n">blue</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span></code></pre></figure> -<p>If we would go Java style, we might have come up with this:</p> +<p>If we went Java style, we might come up with this:</p> <figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="k">type</span> <span class="kt">Json</span> <span class="o">=</span> <span class="nc">String</span> @@ -47,7 +88,7 @@ How about sticking to the Single Responsibility Principle and pushing serializat <span class="k">val</span> <span class="n">json</span><span class="k">:</span> <span class="kt">Json</span> <span class="o">=</span> <span class="nc">ColorJsonSerializer</span><span class="o">.</span><span class="n">toJson</span><span class="o">(</span><span class="n">yellow</span><span class="o">)</span></code></pre></figure> <p class="text-justify">to get a JSON representation of yellow. -That’s better then the previous solution, but we can pimp it using some implicit magic. +That’s better than the previous solution, but we can pimp it using some implicit magic. First let’s make <strong>JsonSerializer.toJson</strong> method look like it’s a method of <strong>Color</strong> class. To achieve that, let’s add an implicit wrapper over <strong>Color</strong>.</p> diff --git a/_site/index.html b/_site/index.html index 5929612..04c3859 100644 --- a/_site/index.html +++ b/_site/index.html @@ -67,6 +67,15 @@

Posts

    +
  • + + +

    + A short one: Covariant type in a contravariant position +

    + It will never happen to you after reading this. +
  • +
  • From b0edd82db778c654784db8f38a69b683b42dc0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82?= Date: Fri, 2 Dec 2016 22:08:18 +0100 Subject: [PATCH 2/2] Add cookies usage page --- _site/about/index.html | 4 ++ _site/feed.xml | 45 +------------------ _site/index.html | 13 ++---- .../2016/11/20/method-function-eta.html | 4 ++ cookies.md | 8 ++++ 5 files changed, 22 insertions(+), 52 deletions(-) create mode 100644 cookies.md diff --git a/_site/about/index.html b/_site/about/index.html index 14012d5..a17f06f 100644 --- a/_site/about/index.html +++ b/_site/about/index.html @@ -41,6 +41,10 @@ + Cookies + + + diff --git a/_site/feed.xml b/_site/feed.xml index 1883470..29601be 100644 --- a/_site/feed.xml +++ b/_site/feed.xml @@ -1,46 +1,5 @@ -Jekyll2016-12-02T21:24:24+01:00http://localhost:4000//MainProgrammer and programming related content. -A short one: Covariant type in a contravariant position2016-12-02T11:00:00+01:002016-12-02T11:00:00+01:00http://localhost:4000/scala/update/2016/12/02/covariant_contravariant<p class="text-justify">There is an exercise in the great <a href="https://www.amazon.com/gp/product/1617290653/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1617290653&amp;linkCode=as2&amp;tag=pawelgebal-20&amp;linkId=f3ec949cadbc0ff936a5aae1dcc51c0a">Functional Programming in Scala</a> book, that requires you to -implement <strong>Option</strong> trait and it’s <strong>getOrElse</strong> method. -My first try on it was:</p> - -<figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="k">sealed</span> <span class="k">trait</span> <span class="nc">Option</span><span class="o">[</span><span class="kt">+A</span><span class="o">]</span> <span class="o">{</span> - - <span class="k">def</span> <span class="n">getOrElse</span><span class="o">(</span><span class="n">default</span><span class="k">:</span> <span class="o">=&gt;</span> <span class="n">A</span><span class="o">)</span><span class="k">:</span> <span class="kt">A</span> <span class="o">=</span> <span class="k">this</span> <span class="k">match</span> <span class="o">{</span> - <span class="k">case</span> <span class="nc">Some</span><span class="o">(</span><span class="n">a</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">a</span> - <span class="k">case</span> <span class="nc">None</span> <span class="k">=&gt;</span> <span class="n">default</span> - <span class="o">}</span> -<span class="o">}</span> - -<span class="k">case</span> <span class="k">class</span> <span class="nc">Some</span><span class="o">[</span><span class="kt">+A</span><span class="o">](</span><span class="n">value</span><span class="k">:</span> <span class="kt">A</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Option</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> -<span class="k">case</span> <span class="k">object</span> <span class="nc">None</span> <span class="k">extends</span> <span class="nc">Option</span><span class="o">[</span><span class="kt">Nothing</span><span class="o">]</span></code></pre></figure> - -<p>IntelliJ Idea was quick to tell me that it’s not a right solution because:</p> - -<figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="nc">Covariant</span> <span class="k">type</span> <span class="kt">A</span> <span class="kt">in</span> <span class="kt">contravariant</span> <span class="kt">position</span> <span class="kt">in</span> <span class="k">type</span> <span class="kt">A</span> <span class="kt">of</span> <span class="kt">value</span> <span class="kt">default.</span></code></pre></figure> - -<p>I looked to the book and noticed that they suggest to use the following definition for <strong>getOrElse</strong>:</p> - -<figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">getOrElse</span><span class="o">[</span><span class="kt">B</span> <span class="k">&gt;:</span> <span class="kt">A</span><span class="o">](</span><span class="n">default</span><span class="k">:</span> <span class="o">=&gt;</span> <span class="n">B</span><span class="o">)</span><span class="k">:</span> <span class="kt">B</span> <span class="o">=</span> <span class="k">this</span> <span class="k">match</span> <span class="o">{</span> - <span class="k">case</span> <span class="nc">Some</span><span class="o">(</span><span class="n">a</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">a</span> - <span class="k">case</span> <span class="nc">None</span> <span class="k">=&gt;</span> <span class="n">default</span> -<span class="o">}</span></code></pre></figure> - -<p class="text-justify">At first I didn’t know why the solution required to use type parameter <strong>B</strong> that is a supertype of <strong>A</strong>. -It turned out to be quite simple. -Notice that <strong>A</strong> is a covariant type parameter for <strong>Option</strong>. -That means for every <strong>A</strong> that is a subtype of <strong>B</strong>, <strong>Option[A]</strong> is a subtype of <strong>Option[B]</strong>. -So whenever we use expression of type <strong>Option[A]</strong>, we have to be able to substitute it with expression of type <strong>Option[B]</strong>. -Study this:</p> - -<figure class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="k">class</span> <span class="nc">B</span> -<span class="k">class</span> <span class="nc">A</span> <span class="k">extends</span> <span class="n">B</span> - -<span class="k">val</span> <span class="n">b</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">B</span><span class="o">]</span> <span class="k">=</span> <span class="nc">None</span> -<span class="k">val</span> <span class="n">a</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="nc">None</span> - -<span class="k">val</span> <span class="n">default</span><span class="k">:</span> <span class="kt">B</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">getOrElse</span><span class="o">(</span><span class="k">new</span> <span class="n">B</span><span class="o">)</span></code></pre></figure> - -<p class="text-justify">Note that in the last line we could use <strong>a</strong> instead of <strong>b</strong> and the code would stay valid. That’s thanks to <nobr><b>[B &gt;: A]</b></nobr> bound in <strong>getOrElse</strong> method definition. If it wasn’t for that <strong>a.getOrElse</strong> would not accept an argument of type <strong>B</strong>. Keep this example in mind and embrace <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov substitution principle</a> when implementing your own classes with type parameters.</p>It will never happen to you after reading this.Type class pattern2016-11-27T11:00:00+01:002016-11-27T11:00:00+01:00http://localhost:4000/scala/update/2016/11/27/type-classes<p>To get the most out of this article I encourage you to put the pieces of code you find here into a scala worksheet and play with it.</p> +Jekyll2016-12-02T22:07:19+01:00http://localhost:4000//MainProgrammer and programming related content. +Type class pattern2016-11-27T11:00:00+01:002016-11-27T11:00:00+01:00http://localhost:4000/scala/update/2016/11/27/type-classes<p>To get the most out of this article I encourage you to put the pieces of code you find here into a scala worksheet and play with it.</p> <p>Let’s have a class that we want to serialize to JSON:</p> diff --git a/_site/index.html b/_site/index.html index 04c3859..5459c80 100644 --- a/_site/index.html +++ b/_site/index.html @@ -41,6 +41,10 @@ + Cookies + + + @@ -67,15 +71,6 @@

    Posts

      -
    • - - -

      - A short one: Covariant type in a contravariant position -

      - It will never happen to you after reading this. -
    • -
    • diff --git a/_site/scala/update/2016/11/20/method-function-eta.html b/_site/scala/update/2016/11/20/method-function-eta.html index 26241ef..7c3814b 100644 --- a/_site/scala/update/2016/11/20/method-function-eta.html +++ b/_site/scala/update/2016/11/20/method-function-eta.html @@ -41,6 +41,10 @@ + Cookies + + + diff --git a/cookies.md b/cookies.md new file mode 100644 index 0000000..9e07d13 --- /dev/null +++ b/cookies.md @@ -0,0 +1,8 @@ +--- +layout: page +title: Cookies +permalink: /cookies/ +--- +This blog uses cookies to track site usage by Google Analytics. + +By browsing this site, you consent to the use of cookies.