<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Type-Theory on CS Theorems</title><link>https://cs.lozic.me/areas/type-theory/</link><description>Recent content in Type-Theory on CS Theorems</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 15 Oct 2027 12:00:00 +0100</lastBuildDate><atom:link href="https://cs.lozic.me/areas/type-theory/index.xml" rel="self" type="application/rss+xml"/><item><title>Parametricity: Theorems for Free</title><link>https://cs.lozic.me/posts/t045-parametricity-theorems-for-free/</link><pubDate>Fri, 15 Oct 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t045-parametricity-theorems-for-free/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;Someone hands you a function and no source:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-haskell" data-lang="haskell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;::&lt;/span&gt; &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;How much can you say about it? The instinct is nothing: any implementation is
possible, that is what polymorphism means.&lt;/p&gt;</description></item><item><title>Progress and Preservation</title><link>https://cs.lozic.me/posts/t044-progress-and-preservation/</link><pubDate>Fri, 01 Oct 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t044-progress-and-preservation/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;Well-typed programs don&amp;rsquo;t go wrong.&amp;rdquo; You have heard it. You have probably said
it. And then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// NullPointerException&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That program is well typed and it went wrong. So either the slogan is false or
it means something narrower than it sounds. It means something narrower, and the
narrowness is precisely specifiable.&lt;/p&gt;</description></item><item><title>Hindley–Milner and Principal Types</title><link>https://cs.lozic.me/posts/t043-hindley-milner-and-principal-types/</link><pubDate>Fri, 24 Sep 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t043-hindley-milner-and-principal-types/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;You write this in OCaml or Haskell and annotate nothing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ocaml" data-lang="ocaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The compiler reports &lt;code&gt;('a -&amp;gt; 'b) -&amp;gt; 'a list -&amp;gt; 'b list&lt;/code&gt;. It found the most
general possible type, on its own, with no hints, and it will reject any call
that does not fit.&lt;/p&gt;</description></item><item><title>The Curry–Howard Correspondence</title><link>https://cs.lozic.me/posts/t042-the-curry-howard-correspondence/</link><pubDate>Fri, 17 Sep 2027 12:00:00 +0100</pubDate><guid>https://cs.lozic.me/posts/t042-the-curry-howard-correspondence/</guid><description>&lt;h2 id="symptom"&gt;Symptom&lt;/h2&gt;
&lt;p&gt;You write a function signature and it looks like a sentence:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-haskell" data-lang="haskell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Read it aloud: if $a$ implies $b$, and $b$ implies $c$, then $a$ implies $c$.
That is transitivity of implication, a rule of logic you have known since school.
And the implementation, &lt;code&gt;f g h = h . g&lt;/code&gt;, is the &lt;em&gt;proof&lt;/em&gt; of it: given evidence for
$a$, apply the first, then apply the second.&lt;/p&gt;</description></item></channel></rss>