<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Conal Elliott &#187; denotational design</title>
	<atom:link href="http://conal.net/blog/tag/denotational-design/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Thu, 25 Jul 2019 18:15:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2F&amp;language=en_US&amp;category=text&amp;title=Conal+Elliott&amp;description=Inspirations+%26amp%3B+experiments%2C+mainly+about+denotative%2Ffunctional+programming+in+Haskell&amp;tags=blog" type="text/html" />
	<item>
		<title>Reimagining matrices</title>
		<link>http://conal.net/blog/posts/reimagining-matrices</link>
		<comments>http://conal.net/blog/posts/reimagining-matrices#comments</comments>
		<pubDate>Mon, 17 Dec 2012 02:45:42 +0000</pubDate>
		<dc:creator><![CDATA[Conal]]></dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[category]]></category>
		<category><![CDATA[denotational design]]></category>
		<category><![CDATA[linear algebra]]></category>
		<category><![CDATA[type class morphism]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=503</guid>
		<description><![CDATA[The function of the imagination is notto make strange things settled, so much asto make settled things strange.- G.K. Chesterton Why is matrix multiplication defined so very differently from matrix addition? If we didn’t know these procedures, could we derive them from first principles? What might those principles be? This post gives a simple semantic [&#8230;]]]></description>
				<content:encoded><![CDATA[<!-- LaTeX macros -->

<!-- teaser -->

<div class=flushright>
<em>The function of the imagination is not<br />to make strange things settled, so much as<br />to make settled things strange.</em><br />- G.K. Chesterton
</div>

<p>Why is matrix multiplication defined so very differently from matrix addition? If we didn’t know these procedures, could we derive them from first principles? What might those principles be?</p>

<p>This post gives a simple semantic model for matrices and then uses it to systematically <em>derive</em> the implementations that we call matrix addition and multiplication. The development illustrates what I call “denotational design”, particularly with type class morphisms. On the way, I give a somewhat unusual formulation of matrices and accompanying definition of matrix “multiplication”.</p>

<p>For more details, see the <a href="https://github.com/conal/linear-map-gadt" title="github repository">linear-map-gadt</a> source code.</p>

<p><strong>Edits:</strong></p>

<ul>
<li>2012–12–17: Replaced lost <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>B</mi></mrow></math> entries in description of matrix addition. Thanks to Travis Cardwell.</li>
<li>2012–12018: Added note about math/browser compatibility.</li>
</ul>

<p><strong>Note:</strong> I’m using MathML for the math below, which appears to work well on Firefox but on neither Safari nor Chrome. I use Pandoc to generate the HTML+MathML from markdown+lhs+LaTeX. There’s probably a workaround using different Pandoc settings and requiring some tweaks to my WordPress installation. If anyone knows how (especially the WordPress end), I’d appreciate some pointers.</p>

<p><span id="more-503"></span></p>

<h3 id="matrices">Matrices</h3>

<p>For now, I’ll write matrices in the usual form: <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mrow><mn>1</mn><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow></mrow></math></p>

<h4 id="addition">Addition</h4>

<p>To add two matrices, we add their corresponding components. If <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mrow><mtext mathvariant="normal">and </mtext><mspace width="0.333em"></mspace></mrow><mi>B</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>B</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>B</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>B</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>B</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mo>,</mo></mrow></math> then <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>+</mo><mi>B</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mn>11</mn></msub><mo>+</mo><msub><mi>B</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mo>.</mo></mrow></math> More succinctly, <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>+</mo><mi>B</mi><msub><mo stretchy="false">)</mo><mrow><mi>i</mi><mi>j</mi></mrow></msub><mo>=</mo><msub><mi>A</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub><mo>.</mo></mrow></math></p>

<h4 id="multiplication">Multiplication</h4>

<p>Multiplication, on the other hand, works quite differently. If <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mrow><mtext mathvariant="normal">and </mtext><mspace width="0.333em"></mspace></mrow><mi>B</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>B</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>B</mi><mrow><mn>1</mn><mi>p</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>B</mi><mrow><mi>m</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>B</mi><mrow><mi>m</mi><mi>p</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mo>,</mo></mrow></math> then <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>∙</mo><mi>B</mi><msub><mo stretchy="false">)</mo><mrow><mi>i</mi><mi>j</mi></mrow></msub><mo>=</mo><munderover><mo>∑</mo><mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></munderover><msub><mi>A</mi><mrow><mi>i</mi><mi>k</mi></mrow></msub><mo>⋅</mo><msub><mi>B</mi><mrow><mi>k</mi><mi>j</mi></mrow></msub><mo>.</mo></mrow></math> This time, we form the dot product of each <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi></mrow></math> row and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>B</mi></mrow></math> column.</p>

<p>Why are these two matrix operations defined so differently? Perhaps these two operations are <em>implementations</em> of more fundamental <em>specifications</em>. If so, then making those specifications explicit could lead us to clear and compelling explanations of matrix addition and multiplication.</p>

<h4 id="transforming-vectors">Transforming vectors</h4>

<p>Simplifying from matrix multiplication, we have transformation of a vector by a matrix. If <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mrow><mtext mathvariant="normal">and </mtext><mspace width="0.333em"></mspace></mrow><mi>x</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>x</mi><mn>1</mn></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>x</mi><mi>m</mi></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mo>,</mo></mrow></math> then <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>⋅</mo><mi>x</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mrow><mn>1</mn><mn>1</mn></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mn>1</mn></msub></mtd><mtd><mo>+</mo></mtd><mtd><mo>⋯</mo></mtd><mtd><mo>+</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mi>m</mi></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd></mtd><mtd><mo>⋱</mo></mtd><mtd></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mn>1</mn></msub></mtd><mtd><mo>+</mo></mtd><mtd><mo>⋯</mo></mtd><mtd><mo>+</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mi>m</mi></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow></mrow></math> More succinctly, <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>⋅</mo><mi>x</mi><msub><mo stretchy="false">)</mo><mi>i</mi></msub><mo>=</mo><munderover><mo>∑</mo><mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></munderover><msub><mi>A</mi><mrow><mi>i</mi><mi>k</mi></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mi>k</mi></msub><mo>.</mo></mrow></math></p>

<h3 id="whats-it-all-about">What’s it all about?</h3>

<p>We can interpret matrices <em>as</em> transformations. Matrix addition then <em>adds</em> transformations:</p>

<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>+</mo><mi>B</mi><mo stretchy="false">)</mo><mspace width="0.167em"></mspace><mi>x</mi><mo>=</mo><mi>A</mi><mspace width="0.167em"></mspace><mi>x</mi><mo>+</mo><mi>B</mi><mspace width="0.167em"></mspace><mi>x</mi></mrow></math></p>

<p>Matrix “multiplication” <em>composes</em> transformations:</p>

<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>∙</mo><mi>B</mi><mo stretchy="false">)</mo><mspace width="0.167em"></mspace><mi>x</mi><mo>=</mo><mi>A</mi><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>B</mi><mspace width="0.167em"></mspace><mi>x</mi><mo stretchy="false">)</mo></mrow></math></p>

<p>What kinds of transformations?</p>

<h4 id="linear-transformations">Linear transformations</h4>

<p>Matrices represent <em>linear</em> transformations. To say that a transformation (or “function” or “map”) <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi></mrow></math> is “linear” means that <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi></mrow></math> preserves the structure of addition and scalar multiplication. In other words, <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mtable><mtr><mtd columnalign="right"><mi>f</mi><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo stretchy="false">)</mo></mtd><mtd columnalign="center"><mo>=</mo></mtd><mtd columnalign="left"><mi>f</mi><mspace width="0.167em"></mspace><mi>x</mi><mo>+</mo><mi>f</mi><mspace width="0.167em"></mspace><mi>y</mi></mtd></mtr><mtr><mtd columnalign="right"><mi>f</mi><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>c</mi><mo>⋅</mo><mi>x</mi><mo stretchy="false">)</mo></mtd><mtd columnalign="center"><mo>=</mo></mtd><mtd columnalign="left"><mi>c</mi><mo>⋅</mo><mi>f</mi><mspace width="0.167em"></mspace><mi>x</mi></mtd></mtr></mtable></mrow></math> Equivalently, <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi></mrow></math> preserves all <em>linear combinations</em>: <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><msub><mi>c</mi><mn>1</mn></msub><mo>⋅</mo><msub><mi>x</mi><mn>1</mn></msub><mo>+</mo><mo>⋯</mo><mo>+</mo><msub><mi>c</mi><mi>m</mi></msub><mo>⋅</mo><msub><mi>x</mi><mi>m</mi></msub><mo stretchy="false">)</mo><mo>=</mo><msub><mi>c</mi><mn>1</mn></msub><mo>⋅</mo><mi>f</mi><mspace width="0.167em"></mspace><msub><mi>x</mi><mn>1</mn></msub><mo>+</mo><mo>⋯</mo><mo>+</mo><msub><mi>c</mi><mi>m</mi></msub><mo>⋅</mo><mi>f</mi><mspace width="0.167em"></mspace><msub><mi>x</mi><mi>m</mi></msub></mrow></math></p>

<p>What does it mean to say that “matrices represent linear transformations”? As we saw in the previous section, we can use a matrix to transform a vector. Our semantic function will exactly be this use, i.e., the <em>meaning</em> of matrix is as a function (map) from vectors to vectors. Moreover, these functions will satisfy the linearity properties above.</p>

<h4 id="representation">Representation</h4>

<p>For simplicity, I’m going structure matrices in a unconventional way. Instead of a rectangular arrangement of numbers, use the following generalized algebraic data type (GADT):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">data</span> a ⊸ b <span class="kw">where</span>
  <span class="dt">Dot</span>   <span class="ot">∷</span> <span class="dt">InnerSpace</span> b <span class="ot">⇒</span>
          b <span class="ot">→</span> (b ⊸ <span class="dt">Scalar</span> b)
  (<span class="fu">:&amp;&amp;</span>) <span class="ot">∷</span> <span class="dt">VS3</span> a c d <span class="ot">⇒</span>  <span class="co">-- vector spaces with same scalar field</span>
          (a ⊸ c) <span class="ot">→</span> (a ⊸ d) <span class="ot">→</span> (a ⊸ c × d)</code></pre>

<p>I’m using the notation “<code>c × d</code>” in place of the usual “<code>(c,d)</code>”. Precedences are such that “<code>×</code>” binds more tightly than “<code>⊸</code>”, which binds more tightly than “<code>→</code>”.</p>

<p>This definition builds on the <a href="http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-VectorSpace.html#t:VectorSpace" title="Hackage documentation"><code>VectorSpace</code></a> class, with its associated <code>Scalar</code> type and <a href="http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-VectorSpace.html#t:InnerSpace" title="Hackage documentation"><code>InnerSpace</code></a> subclass. Using <code>VectorSpace</code> is overkill for linear maps. It suffices to use <a href="http://en.wikipedia.org/wiki/Module_%28mathematics%29" title="Wikipedia entry">module</a>s over <a href="http://en.wikipedia.org/wiki/Semiring" title="Wikipedia entry">semiring</a>s, which means that we don’t assume multiplicative or additive inverses. The more general setting enables many more useful applications than vector spaces do, some of which I will describe in future posts.</p>

<p>The idea here is that a linear map results in either (a) a scalar, in which case it’s equivalent to <code>dot v</code> (partially applied dot product) for some <code>v</code>, or (b) a product, in which case it can be decomposed into two linear maps with simpler range types. Each row in a conventional matrix corresponds to <code>Dot v</code> for some vector <code>v</code>, and the stacking of rows corresponds to nested applications of <code>(:&amp;&amp;)</code>.</p>

<h4 id="semantics">Semantics</h4>

<p>The semantic function, <code>apply</code>, interprets a representation of a linear map as a function (satisfying linearity):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply <span class="ot">∷</span> (a ⊸ b) <span class="ot">→</span> (a <span class="ot">→</span> b)
apply (<span class="dt">Dot</span> b)   <span class="fu">=</span> dot b
apply (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">=</span> apply f <span class="fu">&amp;&amp;&amp;</span> apply g</code></pre>

<p>where, <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Arrow.html#v:-38--38--38-" title="Hackage documentation"><code>(&amp;&amp;&amp;)</code></a> is from <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Arrow.html" title="Hackage documentation"><code>Control.Arrow</code></a>.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(<span class="fu">&amp;&amp;&amp;</span>) <span class="ot">∷</span> <span class="dt">Arrow</span> (↝) <span class="ot">⇒</span> (a ↝ b) <span class="ot">→</span> (a ↝ c) <span class="ot">→</span> (a ↝ (b,c))</code></pre>

<p>For functions,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">&amp;&amp;&amp;</span> g) a <span class="fu">=</span> (f a, g a)</code></pre>

<h3 id="functions-linearity-and-multilinearity">Functions, linearity, and multilinearity</h3>

<p>Functions form a vector space, with scaling and addition defined “pointwise”. Instances from the <a href="http://hackage.haskell.org/package/vector-space" title="Hackage package">vector-space</a> package:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">AdditiveGroup</span> v <span class="ot">⇒</span> <span class="dt">AdditiveGroup</span> (a <span class="ot">→</span> v) <span class="kw">where</span>
  zeroV   <span class="fu">=</span> pure   zeroV
  (<span class="fu">^+^</span>)   <span class="fu">=</span> liftA2 (<span class="fu">^+^</span>)
  negateV <span class="fu">=</span> <span class="fu">fmap</span>   negateV

<span class="kw">instance</span> <span class="dt">VectorSpace</span> v <span class="ot">⇒</span> <span class="dt">VectorSpace</span> (a <span class="ot">→</span> v) <span class="kw">where</span>
  <span class="kw">type</span> <span class="dt">Scalar</span> (a <span class="ot">→</span> v) <span class="fu">=</span> a <span class="ot">→</span> <span class="dt">Scalar</span> v
  (<span class="fu">*^</span>) s <span class="fu">=</span> <span class="fu">fmap</span> (s <span class="fu">*^</span>)</code></pre>

<p>I wrote the definitions in this form to fit a template for applicative functors in general. Inlining the definitions of <code>pure</code>, <code>liftA2</code>, and <code>fmap</code> on functions, we get the following equivalent instances:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">AdditiveGroup</span> v <span class="ot">⇒</span> <span class="dt">AdditiveGroup</span> (a <span class="ot">→</span> v) <span class="kw">where</span>
  zeroV     <span class="fu">=</span> λ _ <span class="ot">→</span> zeroV
  f <span class="fu">^+^</span> g   <span class="fu">=</span> λ a <span class="ot">→</span> f a <span class="fu">^+^</span> g a
  negateV f <span class="fu">=</span> λ a <span class="ot">→</span> negateV (f a)

<span class="kw">instance</span> <span class="dt">VectorSpace</span> v <span class="ot">⇒</span> <span class="dt">VectorSpace</span> (a <span class="ot">→</span> v) <span class="kw">where</span>
  <span class="kw">type</span> <span class="dt">Scalar</span> (a <span class="ot">→</span> v) <span class="fu">=</span> a <span class="ot">→</span> <span class="dt">Scalar</span> v
  s <span class="fu">*^</span> f <span class="fu">=</span> λ a <span class="ot">→</span> s <span class="fu">*^</span> f a</code></pre>

<p>In math, we usually say that dot product is “bilinear”, or “linear in each argument”, i.e.,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (s <span class="fu">*^</span> u,v) ≡ s <span class="fu">*^</span> dot (u,v)
dot (u <span class="fu">^+^</span> w, v) ≡ dot (u,v) <span class="fu">^+^</span> dot (w,v)</code></pre>

<p>Similarly for the second argument:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (u,s <span class="fu">*^</span> v) ≡ s <span class="fu">*^</span> dot (u,v)
dot (u, v <span class="fu">^+^</span> w) ≡ dot (u,v) <span class="fu">^+^</span> dot (u,w)</code></pre>

<p>Now recast the first of these properties in a curried form:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (s <span class="fu">*^</span> u) v ≡ s <span class="fu">*^</span> dot u v</code></pre>

<p>i.e.,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (s <span class="fu">*^</span> u)
 ≡ <span class="co">{- η-expand -}</span>
λ v <span class="ot">→</span> dot (s <span class="fu">*^</span> u) v
 ≡ <span class="co">{- &quot;bilinearity&quot; -}</span>
λ v <span class="ot">→</span> s <span class="fu">*^</span> dot u v
 ≡ <span class="co">{- (*^) on functions -}</span>
λ v <span class="ot">→</span> (s <span class="fu">*^</span> dot u) v
 ≡ <span class="co">{- η-contract -}</span>
s <span class="fu">*^</span> dot u</code></pre>

<p>Likewise,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (u <span class="fu">^+^</span> v)
 ≡ <span class="co">{- η-expand -}</span>
λ w <span class="ot">→</span> dot (u <span class="fu">^+^</span> v) w
 ≡ <span class="co">{- &quot;bilinearity&quot; -}</span>
λ w <span class="ot">→</span> dot u w <span class="fu">^+^</span> dot v w
 ≡ <span class="co">{- (^+^) on functions -}</span>
dot u <span class="fu">^+^</span> dot v</code></pre>

<p>Thus, when “bilinearity” is recast in terms of curried functions, it becomes just linearity. (The same reasoning applies more generally to multilinearity.)</p>

<p>Note that we could also define function addition as follows:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">f <span class="fu">^+^</span> g <span class="fu">=</span> add ∘ (f <span class="fu">&amp;&amp;&amp;</span> g)</code></pre>

<p>where</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add <span class="fu">=</span> <span class="fu">uncurry</span> (<span class="fu">^+^</span>)</code></pre>

<p>This uncurried form will come in handy in derivations below.</p>

<h3 id="deriving-matrix-operations">Deriving matrix operations</h3>

<h4 id="addition-1">Addition</h4>

<p>We’ll add two linear maps using the <a href="http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-AdditiveGroup.html#v:-94--43--94-" title="Hackage documentation"><code>(^+^)</code></a> operation from <a href="http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-AdditiveGroup.html" title="Hackage documentation"><code>Data.AdditiveGroup</code></a>.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(<span class="fu">^+^</span>) <span class="ot">∷</span> (a ⊸ b) <span class="ot">→</span> (a ⊸ b) <span class="ot">→</span> (a ⊸ b)</code></pre>

<p>Following the principle of semantic <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on type class morphisms">type class morphism</a>s, the specification simply says that the meaning of the sum is the sum of the meanings:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">^+^</span> g) ≡ apply f <span class="fu">^+^</span> apply g</code></pre>

<p>which is half of the definition of “linearity” for <code>apply</code>.</p>

<p>The game plan (as always) is to use the semantic specification to derive (or “calculate”) a correct implementation of each operation. For addition, this goal means we want to come up with a definition like</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">f <span class="fu">^+^</span> g <span class="fu">=</span> <span class="fu">&lt;</span>rhs<span class="fu">&gt;</span></code></pre>

<p>where <code>&lt;rhs&gt;</code> is some expression in terms of <code>f</code> and <code>g</code> whose <em>meaning</em> is the same as the meaning as <code>f ^+^ g</code>, i.e., where</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">^+^</span> g) ≡ apply <span class="fu">&lt;</span>rhs<span class="fu">&gt;</span></code></pre>

<p>Since Haskell has convenient pattern matching, we’ll use it for our definition of <code>(^+^)</code> above. Addition has two arguments, and our data type has two constructors, there are at most four different cases to consider.</p>

<p>First, add <code>Dot</code> and <code>Dot</code>. The specification</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">^+^</span> g) ≡ apply f <span class="fu">^+^</span> apply g</code></pre>

<p>specializes to</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> b <span class="fu">^+^</span> <span class="dt">Dot</span> c) ≡ apply (<span class="dt">Dot</span> b) <span class="fu">^+^</span> apply (<span class="dt">Dot</span> c)</code></pre>

<p>Now simplify the right-hand side (RHS):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> b) <span class="fu">^+^</span> apply (<span class="dt">Dot</span> c)
 ≡ <span class="co">{- apply definition -}</span>
dot b <span class="fu">^+^</span> dot c
 ≡ <span class="co">{- (bi)linearity of dot, as described above -}</span>
dot (b <span class="fu">^+^</span> c)
 ≡ <span class="co">{- apply definition -}</span>
apply (<span class="dt">Dot</span> (b <span class="fu">^+^</span> c))</code></pre>

<p>So our specialized specification becomes</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> b <span class="fu">^+^</span> <span class="dt">Dot</span> c) ≡ apply (<span class="dt">Dot</span> (b <span class="fu">^+^</span> c))</code></pre>

<p>which is implied by</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="dt">Dot</span> b <span class="fu">^+^</span> <span class="dt">Dot</span> c ≡ <span class="dt">Dot</span> (b <span class="fu">^+^</span> c)</code></pre>

<p>and easily satisfied by the following partial definition (replacing “<code>≡</code>” by “<code>=</code>”):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="dt">Dot</span> b <span class="fu">^+^</span> <span class="dt">Dot</span> c <span class="fu">=</span> <span class="dt">Dot</span> (b <span class="fu">^+^</span> c)</code></pre>

<p>Now consider the case of addition with two <code>(:&amp;&amp;)</code> constructors:</p>

<p>The specification specializes to</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply ((f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">:&amp;&amp;</span> k)) ≡ apply (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> apply (h <span class="fu">:&amp;&amp;</span> k)</code></pre>

<p>As with <code>Dot</code>, simplify the RHS:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> apply (h <span class="fu">:&amp;&amp;</span> k)
 ≡ <span class="co">{- apply definition -}</span>
(apply f <span class="fu">&amp;&amp;&amp;</span> apply g) <span class="fu">^+^</span> (apply h <span class="fu">&amp;&amp;&amp;</span> apply k)
 ≡ <span class="co">{- See below -}</span>
(apply f <span class="fu">^+^</span> apply h) <span class="fu">&amp;&amp;&amp;</span> (apply g <span class="fu">^+^</span> apply k)
 ≡ <span class="co">{- induction -}</span>
apply (f <span class="fu">^+^</span> h) <span class="fu">&amp;&amp;&amp;</span> apply (g <span class="fu">^+^</span> k)
 ≡ <span class="co">{- apply definition -}</span>
apply ((f <span class="fu">^+^</span> h) <span class="fu">:&amp;&amp;</span> (g <span class="fu">^+^</span> k))</code></pre>

<p>I used the following property (on functions):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">&amp;&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">&amp;&amp;&amp;</span> k) ≡ (f <span class="fu">^+^</span> h) <span class="fu">&amp;&amp;&amp;</span> (g <span class="fu">^+^</span> k)</code></pre>

<p>Proof:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">&amp;&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">&amp;&amp;&amp;</span> k)
 ≡ <span class="co">{- η-expand -}</span>
λ x <span class="ot">→</span> ((f <span class="fu">&amp;&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">&amp;&amp;&amp;</span> k)) x
 ≡ <span class="co">{- (&amp;&amp;&amp;) definition for functions -}</span>
λ x <span class="ot">→</span> (f x, g x) <span class="fu">^+^</span> (h x, k x)
 ≡ <span class="co">{- (^+^) definition for pairs -}</span>
λ x <span class="ot">→</span> (f x <span class="fu">^+^</span> h x, g x <span class="fu">^+^</span> k x)
 ≡ <span class="co">{- (^+^) definition for functions -}</span>
λ x <span class="ot">→</span> ((f <span class="fu">^+^</span> h) x, (g <span class="fu">^+^</span> k) x)
 ≡ <span class="co">{- (&amp;&amp;&amp;) definition for functions -}</span>
(f <span class="fu">^+^</span> h) <span class="fu">&amp;&amp;&amp;</span> (g <span class="fu">^+^</span> k)</code></pre>

<p>The specification becomes</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply ((f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">:&amp;&amp;</span> k)) ≡ apply ((f <span class="fu">^+^</span> h) <span class="fu">:&amp;&amp;</span> (g <span class="fu">^+^</span> k))</code></pre>

<p>which is easily satisfied by the following partial definition</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">:&amp;&amp;</span> k) <span class="fu">=</span> (f <span class="fu">^+^</span> h) <span class="fu">:&amp;&amp;</span> (g <span class="fu">^+^</span> k)</code></pre>

<p>The other two cases are (a) <code>Dot</code> and <code>(:&amp;&amp;)</code>, and (b) <code>(:&amp;&amp;)</code> and <code>Dot</code>, but they don’t type-check (assuming that pairs are not scalars).</p>

<h3 id="composing-linear-maps">Composing linear maps</h3>

<p>I’ll write linear map composition as “<code>g ∘ f</code>”, with type</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(∘) <span class="ot">∷</span> (b ⊸ c) <span class="ot">→</span> (a ⊸ b) <span class="ot">→</span> (a ⊸ c)</code></pre>

<p>This notation is thanks to a <code>Category</code> instance, which depends on a generalized <code>Category</code> class that uses the recent <code>ConstraintKinds</code> language extension. (See the <a href="https://github.com/conal/linear-map-gadt" title="github repository">source code</a>.)</p>

<p>Following the semantic <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on type class morphisms">type class morphism</a> principle again, the specification says that the meaning of the composition is the composition of the meanings:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (g ∘ f) ≡ apply g ∘ apply f</code></pre>

<p>In the following, note that the <code>∘</code> operator binds more tightly than <code>&amp;&amp;&amp;</code>, so <code>f ∘ h &amp;&amp;&amp; g ∘ h</code> means <code>(f ∘ h) &amp;&amp;&amp; (g ∘ h)</code>.</p>

<h4 id="derivation">Derivation</h4>

<p>Again, since there are two constructors, we have four possible cases cases. We can handle two of these cases together, namely <code>(:&amp;&amp;)</code> and anything. The specification:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply ((f <span class="fu">:&amp;&amp;</span> g) ∘ h) ≡ apply (f <span class="fu">:&amp;&amp;</span> g) ∘ apply h</code></pre>

<p>Reasoning proceeds as above, simplifying the RHS of the constructor-specialized specification.</p>

<p>Simplify the RHS:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">:&amp;&amp;</span> g) ∘ apply h
 ≡ <span class="co">{- apply definition -}</span>
(apply f <span class="fu">&amp;&amp;&amp;</span> apply g) ∘ apply h
 ≡ <span class="co">{- see below -}</span>
apply f ∘ apply h <span class="fu">&amp;&amp;&amp;</span> apply g ∘ apply h
 ≡ <span class="co">{- induction -}</span>
apply (f ∘ h) <span class="fu">&amp;&amp;&amp;</span> apply (g ∘ h)
 ≡ <span class="co">{- apply definition -}</span>
apply (f ∘ h <span class="fu">:&amp;&amp;</span> g ∘ h)</code></pre>

<p>This simplification uses the following property of functions:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(p <span class="fu">&amp;&amp;&amp;</span> q) ∘ r ≡ p ∘ r <span class="fu">&amp;&amp;&amp;</span> q ∘ r</code></pre>

<p>Sufficient definition:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">:&amp;&amp;</span> g) ∘ h <span class="fu">=</span> f ∘ h <span class="fu">:&amp;&amp;</span> g ∘ h</code></pre>

<p>We have two more cases, specified as follows:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> c ∘ <span class="dt">Dot</span> b) ≡ apply (<span class="dt">Dot</span> c) ∘ apply (<span class="dt">Dot</span> b)

apply (<span class="dt">Dot</span> c ∘ (f <span class="fu">:&amp;&amp;</span> g)) ≡ apply (<span class="dt">Dot</span> c) ∘ apply (f <span class="fu">:&amp;&amp;</span> g)</code></pre>

<p>Based on types, <code>c</code> must be a scalar in the first case and a pair in the second. (<code>Dot b</code> produces a scalar, while <code>f :&amp;&amp; g</code> produces a pair.) Thus, we can write these two cases more specifically:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> s ∘ <span class="dt">Dot</span> b) ≡ apply (<span class="dt">Dot</span> s) ∘ apply (<span class="dt">Dot</span> b)

apply (<span class="dt">Dot</span> (a,b) ∘ (f <span class="fu">:&amp;&amp;</span> g)) ≡ apply (<span class="dt">Dot</span> (a,b)) ∘ apply (f <span class="fu">:&amp;&amp;</span> g)</code></pre>

<p>In the derivation, I won’t spell out as many details as before. Simplify the RHSs:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">  apply (<span class="dt">Dot</span> s) ∘ apply (<span class="dt">Dot</span> b)
≡ dot s ∘ dot b
≡ dot (s <span class="fu">*^</span> b)
≡ apply (<span class="dt">Dot</span> (s <span class="fu">*^</span> b))</code></pre>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">  apply (<span class="dt">Dot</span> (a,b)) ∘ apply (f <span class="fu">:&amp;&amp;</span> g)
≡ dot (a,b) ∘ (apply f <span class="fu">&amp;&amp;&amp;</span> apply g)
≡ add ∘ (dot a ∘ apply f <span class="fu">&amp;&amp;&amp;</span> dot b ∘ apply g)
≡ dot a ∘ apply f <span class="fu">^+^</span> dot b ∘ apply g
≡ apply (<span class="dt">Dot</span> a ∘ f <span class="fu">^+^</span> <span class="dt">Dot</span> b ∘ g)</code></pre>

<p>I’ve used the following properties of functions:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (a,b)             ≡ add ∘ (dot a <span class="fu">***</span> dot b)

(r <span class="fu">***</span> s) ∘ (p <span class="fu">&amp;&amp;&amp;</span> q) ≡ r ∘ p <span class="fu">&amp;&amp;&amp;</span> s ∘ q

add ∘ (p <span class="fu">&amp;&amp;&amp;</span> q)       ≡ p <span class="fu">^+^</span> q

apply (f <span class="fu">^+^</span> g)       ≡ apply f <span class="fu">^+^</span> apply g</code></pre>

<p>Implementation:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"> <span class="dt">Dot</span> s     ∘ <span class="dt">Dot</span> b     <span class="fu">=</span> <span class="dt">Dot</span> (s <span class="fu">*^</span> b)
 <span class="dt">Dot</span> (a,b) ∘ (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">=</span> <span class="dt">Dot</span> a ∘ f <span class="fu">^+^</span> <span class="dt">Dot</span> b ∘ g</code></pre>

<h3 id="cross-products">Cross products</h3>

<p>Another <code>Arrow</code> operation handy for linear maps is the parallel composition (product):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(<span class="fu">***</span>) <span class="ot">∷</span> (a ⊸ c) <span class="ot">→</span> (b ⊸ d) <span class="ot">→</span> (a × b ⊸ c × d)</code></pre>

<p>The specification says that <code>apply</code> distributes over <code>(***)</code>. In other words, the meaning of the product is the product of the meanings.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">***</span> g) <span class="fu">=</span> apply f <span class="fu">***</span> apply g</code></pre>

<p>Where, on functions,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">p <span class="fu">***</span> q <span class="fu">=</span> λ (a,b) <span class="ot">→</span> (p a, q b)
        ≡ p ∘ <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> q ∘ <span class="fu">snd</span></code></pre>

<p>Simplify the specifications RHS:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">  apply f <span class="fu">***</span> apply g
≡ apply f ∘ <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> apply g ∘ <span class="fu">snd</span></code></pre>

<p>If we knew how to represent <code>fst</code> and <code>snd</code> via our linear map constructors, we’d be nearly done. Instead, let’s suppose we have the following functions.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">compFst <span class="ot">∷</span> <span class="dt">VS3</span> a b c <span class="ot">⇒</span> a ⊸ c <span class="ot">→</span> a × b ⊸ c
compSnd <span class="ot">∷</span> <span class="dt">VS3</span> a b c <span class="ot">⇒</span> b ⊸ c <span class="ot">→</span> a × b ⊸ c</code></pre>

<p>specified as follows:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (compFst f) ≡ apply f ∘ <span class="fu">fst</span>
apply (compSnd g) ≡ apply g ∘ <span class="fu">snd</span></code></pre>

<p>With these two functions (to be defined) in hand, let’s try again.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">  apply f <span class="fu">***</span> apply g
≡ apply f ∘ <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> apply g ∘ <span class="fu">snd</span>
≡ apply (compFst f) <span class="fu">&amp;&amp;&amp;</span> apply (compSnd g)
≡ apply (compFst f <span class="fu">:&amp;&amp;</span> compSnd g)</code></pre>

<h4 id="composing-with-fst-and-snd">Composing with <code>fst</code> and <code>snd</code></h4>

<p>I’ll elide even more of the derivation this time, focusing reasoning on the meanings. Relating to the representation is left as an exercise. The key steps in the derivation:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot a     ∘ <span class="fu">fst</span> ≡ dot (a,<span class="dv">0</span>)

(f <span class="fu">&amp;&amp;&amp;</span> g) ∘ <span class="fu">fst</span> ≡ f ∘ <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> g ∘ <span class="fu">fst</span>

dot b     ∘ <span class="fu">snd</span> ≡ dot (<span class="dv">0</span>,b)

(f <span class="fu">&amp;&amp;&amp;</span> g) ∘ <span class="fu">snd</span> ≡ f ∘ <span class="fu">snd</span> <span class="fu">&amp;&amp;&amp;</span> g ∘ <span class="fu">snd</span></code></pre>

<p>Implementation:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">compFst (<span class="dt">Dot</span> a)   <span class="fu">=</span> <span class="dt">Dot</span> (a,zeroV)
compFst (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">=</span> compFst f <span class="fu">&amp;&amp;&amp;</span> compFst g

compSnd (<span class="dt">Dot</span> b)   <span class="fu">=</span> <span class="dt">Dot</span> (zeroV,b)
compSnd (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">=</span> compSnd f <span class="fu">&amp;&amp;&amp;</span> compSnd g</code></pre>

<p>where <code>zeroV</code> is the zero vector.</p>

<p>Given <code>compFst</code> and <code>compSnd</code>, we can implement <code>fst</code> and <code>snd</code> as linear maps simply as <code>compFst id</code> and <code>compSnd id</code>, where <code>id</code> is the (polymorphic) identity linear map.</p>

<h3 id="reflections">Reflections</h3>

<p>This post reflects an approach to programming that I apply wherever I’m able. As a summary:</p>

<ul>
<li>Look for an elegant <em>what</em> behind a familiar <em>how</em>.</li>
<li><em>Define</em> a semantic function for each data type.</li>
<li><em>Derive</em> a correct implementation from the semantics.</li>
</ul>

<p>You can find more examples of this methodology elsewhere in this blog and in the paper <a href="http://conal.net/papers/type-class-morphisms/"><em>Denotational design with type class morphisms</em></a>.</p>
<p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=503&amp;md5=061f6fb371675342c9a006b8ec5376e9"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/reimagining-matrices/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Freimagining-matrices&amp;language=en_GB&amp;category=text&amp;title=Reimagining+matrices&amp;description=The+function+of+the+imagination+is+notto+make+strange+things+settled%2C+so+much+asto+make+settled+things+strange.-+G.K.+Chesterton+Why+is+matrix+multiplication+defined+so+very+differently+from+matrix...&amp;tags=category%2Cdenotational+design%2Clinear+algebra%2Ctype+class+morphism%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
