Skip to content

Commit 78868b2

Browse files
committed
Added gitignore to ignore bult files, also added a basic Makefil
1 parent 25a25c1 commit 78868b2

File tree

8 files changed

+414
-342
lines changed

8 files changed

+414
-342
lines changed

Book/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Ignore the built files
2+
build/

Book/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
run :
3+
python3 build.py

Book/build/Dimensions/Introduction.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ <h1 id="introduction">Introduction</h1>
3030
<p>What’s the relation between these? A <em>quantity</em> has a <em>dimension</em>. The number describing the distance between Stockholm and Gothenburg is of the type length. A <em>quantity</em> also has a <em>unit</em> that relates the number to a known definite distance. The unit of a quantity must describe the dimension of the quantity. It’s not possible to describe a distance with joule. However, describing a distance is possible with both metres and inches. Those are two different units describing a quantity of the same dimension.</p>
3131
<p>The dimension of a quantity is often implicitly understood given its unit. If I have a rope of 1 metre, you know it’s a length I’m talking about.</p>
3232
<p>There are 7 <em>base dimensions</em>, each with a corresponding SI-unit.</p>
33+
<figure>
34+
<img src="Base_dimensions.png" alt="The 7 base dimensions" class="float-img-right" /><figcaption>The 7 base dimensions</figcaption>
35+
</figure>
3336
<ul>
3437
<li>Length (metre)</li>
3538
<li>Mass (kilogram)</li>
@@ -46,6 +49,11 @@ <h1 id="introduction">Introduction</h1>
4649
</main>
4750

4851
<footer>
52+
<nav>
53+
<span>Previous: <a href="../index.html">Table of contents</a></span>
54+
<a href="../index.html">Table of contents</a>
55+
<span>Next: <a href="../Dimensions/Value-level dimensions.html">Value-level dimensions</a></span>
56+
</nav>
4957
Licensed under the GPL by the Kandidatboisen (2018)
5058
</footer>
5159
</body>

Book/build/Dimensions/Quantities.html

Lines changed: 304 additions & 200 deletions
Large diffs are not rendered by default.

Book/build/Dimensions/Type-level dimensions.html

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<a href="../index.html"><h1>Learn You a <span class="physics">Physics</span> for Great Good!</h1></a>
1313
<h1>&gt;&gt;&gt; WORK IN PROGRESS &lt;&lt;&lt;</h1>
1414
<nav>
15-
<span>Previous: <a href="../Dimensions/Value-level dimensions.html">Value-level dimensions</a></span>
15+
<span>Previous: <a href="../Dimensions/Testing of value-level dimensions.html">Testing of value-level dimensions</a></span>
1616
<a href="../index.html">Table of contents</a>
1717
<span>Next: <a href="../Dimensions/Quantities.html">Quantities</a></span>
1818
</nav>
@@ -22,6 +22,9 @@ <h1>&gt;&gt;&gt; WORK IN PROGRESS &lt;&lt;&lt;</h1>
2222
<h1 id="type-level-dimensions">Type-level dimensions</h1>
2323
<p>We will now implement <em>type-level</em> dimensions. What is type-level? When one usually programs (in Haskell), one operatates (e.g. adds) on values (e.g. <code>1</code> and <code>2</code>). This is on <em>value-level</em>. Now we’ll do the same thing but on <em>type-level</em>, that is, perform operations on types.</p>
2424
<p>What’s the purpose of type-level dimensions? It’s so we’ll notice as soon as compile-time if we’ve written something incorrect. E.g. adding a length and an area is not allowed since they have different dimensions.</p>
25+
<figure>
26+
<img src="Lengths_and_area.png" alt="Adding lengths is OK. Adding lengths and areas is not OK." /><figcaption>Adding lengths is OK. Adding lengths and areas is not OK.</figcaption>
27+
</figure>
2528
<p>This implemention is very similar to the value-level one. It would be possible to only have one implementation by using <code>Data.Proxy</code>. But it would be trickier. This way is lengthier but easier to understand.</p>
2629
<p>To be able to do type-level programming, we’ll need a nice stash of GHC-extensions.</p>
2730
<div class="sourceCode" id="cb1"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="ot">{-# LANGUAGE DataKinds #-}</span></a>
@@ -45,7 +48,7 @@ <h1 id="type-level-dimensions">Type-level dimensions</h1>
4548
<a class="sourceLine" id="cb2-12" data-line-number="12">, <span class="dt">One</span></a>
4649
<a class="sourceLine" id="cb2-13" data-line-number="13">)</a>
4750
<a class="sourceLine" id="cb2-14" data-line-number="14"><span class="kw">where</span></a></code></pre></div>
48-
<p>We’ll need to be able to operate on integers on type-level. Instead of implementing it ourselves, we will just import the machinery so we can focus on the physics-part.</p>
51+
<p>We’ll need to be able to operate on integers on the type-level. Instead of implementing it ourselves, we will just import the machinery so we can focus on the physics-part.</p>
4952
<div class="sourceCode" id="cb3"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" data-line-number="1"><span class="kw">import</span> <span class="dt">Numeric.NumType.DK.Integers</span></a></code></pre></div>
5053
<p>We make a <em>kind</em> for dimensions, just like we in the previous section made <em>type</em> for dimensions. On value-level we made a <em>type</em> with <em>values</em>. Now we make a <em>kind</em> with <em>types</em>. The meaning is exactly the same, except we have moved “one step up”.</p>
5154
<div class="sourceCode" id="cb4"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Dim</span> <span class="fu">=</span> <span class="dt">Dim</span> <span class="dt">TypeInt</span> <span class="co">-- Length</span></a>
@@ -83,11 +86,13 @@ <h1 id="type-level-dimensions">Type-level dimensions</h1>
8386
<a class="sourceLine" id="cb7-5" data-line-number="5"><span class="kw">type</span> <span class="dt">Temperature</span> <span class="fu">=</span> <span class="ch">&#39;Dim Zero Zero Zero Zero Pos1 Zero Zero</span></a>
8487
<a class="sourceLine" id="cb7-6" data-line-number="6"><span class="kw">type</span> <span class="dt">Substance</span> <span class="fu">=</span> <span class="ch">&#39;Dim Zero Zero Zero Zero Zero Pos1 Zero</span></a>
8588
<a class="sourceLine" id="cb7-7" data-line-number="7"><span class="kw">type</span> <span class="dt">Luminosity</span> <span class="fu">=</span> <span class="ch">&#39;Dim Zero Zero Zero Zero Zero Zero Pos1</span></a></code></pre></div>
89+
<p><code>'Dim</code> is used to distinguish between the <em>type</em> <code>Dim</code> (left-hand-side of the <code>data Dim</code> definition) and the <em>type constructor</em> <code>Dim</code> (right-hand-side of the <code>data Dim</code> definition, with <code>DataKinds</code>-perspective). <code>'Dim</code> refers to the type constructor. Both are created when using <code>DataKinds</code>.</p>
90+
<p><code>Pos1</code>, <code>Neg1</code> and so on corresponds to <code>1</code> and <code>-1</code> in the imported package, which operates on type-level integers.</p>
91+
<p><strong>Exercise.</strong> Create types for velocity, acceleration and the scalar.</p>
92+
<p><strong>Solution.</strong></p>
8693
<div class="sourceCode" id="cb8"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" data-line-number="1"><span class="kw">type</span> <span class="dt">Velocity</span> <span class="fu">=</span> <span class="ch">&#39;Dim Pos1 Zero Neg1 Zero Zero Zero Zero</span></a>
8794
<a class="sourceLine" id="cb8-2" data-line-number="2"><span class="kw">type</span> <span class="dt">Acceleration</span> <span class="fu">=</span> <span class="ch">&#39;Dim Pos1 Zero Neg2 Zero Zero Zero Zero</span></a></code></pre></div>
8895
<div class="sourceCode" id="cb9"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" data-line-number="1"><span class="kw">type</span> <span class="dt">One</span> <span class="fu">=</span> <span class="ch">&#39;Dim Zero Zero Zero Zero Zero Zero Zero</span></a></code></pre></div>
89-
<p><code>'Dim</code> is used to distinguish between the <em>type</em> <code>Dim</code> (left-hand-side of the <code>data Dim</code> definition) and the <em>type constructor</em> <code>Dim</code> (right-hand-side of the <code>data Dim</code> definition, with <code>DataKinds</code>-perspective). <code>'Dim</code> refers to the type constructor. Both are created when using <code>DataKinds</code>.</p>
90-
<p><code>Pos1</code>, <code>Neg1</code> and so on corresponds to <code>1</code> and <code>-1</code> in the imported package, which operates on type-level integers.</p>
9196
<h2 id="multiplication-and-division">Multiplication and division</h2>
9297
<p>Let’s implement multiplication and division on type-level. After such an operation a new dimension is created. And from the previous section we already know what the dimension should look like. To translate to Haskell-language: “after such an operation a new <em>type</em> is created”. How does one implement that? With <code>type family</code>! <code>type family</code> can easiest be thought of as a function on the type-level.</p>
9398
<div class="sourceCode" id="cb10"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" data-line-number="1"><span class="kw">type</span> family <span class="dt">Mul</span> (<span class="ot">d1 ::</span> <span class="dt">Dim</span>) (<span class="ot">d2 ::</span> <span class="dt">Dim</span>) <span class="kw">where</span></a>
@@ -100,22 +105,35 @@ <h2 id="multiplication-and-division">Multiplication and division</h2>
100105
<li><code>Mul</code> is the name of the function.</li>
101106
<li><code>d1 :: Dim</code> is read as “the <em>type</em> <code>d1</code> has <em>kind</em> <code>Dim</code>”.</li>
102107
</ul>
103-
<p>Division is very similar.</p>
108+
<p><strong>Exercise.</strong> As you would suspect, division is very similar, so why don’t you try ’n implement it yourself?</p>
109+
<p><strong>Solution.</strong></p>
104110
<div class="sourceCode" id="cb11"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" data-line-number="1"><span class="kw">type</span> family <span class="dt">Div</span> (<span class="ot">d1 ::</span> <span class="dt">Dim</span>) (<span class="ot">d2 ::</span> <span class="dt">Dim</span>) <span class="kw">where</span></a>
105111
<a class="sourceLine" id="cb11-2" data-line-number="2"> <span class="dt">Div</span> (<span class="ch">&#39;Dim le1 ma1 ti1 cu1 te1 su1 lu1) </span></a>
106112
<a class="sourceLine" id="cb11-3" data-line-number="3"> (<span class="ch">&#39;Dim le2 ma2 ti2 cu2 te2 su2 lu2) =</span></a>
107113
<a class="sourceLine" id="cb11-4" data-line-number="4"> <span class="ch">&#39;Dim (le1-le2) (ma1-ma2) (ti1-ti2) (cu1-cu2)</span></a>
108114
<a class="sourceLine" id="cb11-5" data-line-number="5"> (te1<span class="fu">-</span>te2) (su1<span class="fu">-</span>su2) (lu1<span class="fu">-</span>lu2)</a></code></pre></div>
109-
<p>Let’s create some example <em>types</em> for dimensions with multiplication and division.</p>
110-
<div class="sourceCode" id="cb12"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" data-line-number="1"><span class="kw">type</span> <span class="dt">Velocity&#39;</span> <span class="fu">=</span> <span class="dt">Length</span> <span class="ot">`Div`</span> <span class="dt">Time</span></a>
111-
<a class="sourceLine" id="cb12-2" data-line-number="2"><span class="kw">type</span> <span class="dt">Area</span> <span class="fu">=</span> <span class="dt">Length</span> <span class="ot">`Mul`</span> <span class="dt">Length</span></a>
112-
<a class="sourceLine" id="cb12-3" data-line-number="3"><span class="kw">type</span> <span class="dt">Force</span> <span class="fu">=</span> <span class="dt">Mass</span> <span class="ot">`Mul`</span> <span class="dt">Length</span></a>
113-
<a class="sourceLine" id="cb12-4" data-line-number="4"><span class="kw">type</span> <span class="dt">Impulse</span> <span class="fu">=</span> <span class="dt">Force</span> <span class="ot">`Mul`</span> <span class="dt">Time</span></a></code></pre></div>
115+
<p><strong>Exercise.</strong> Implement a type-level function for raising a dimension to the power of some integer.</p>
116+
<p><strong>Solution.</strong></p>
117+
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" data-line-number="1"><span class="kw">type</span> family <span class="dt">Power</span> (<span class="ot">d ::</span> <span class="dt">Dim</span>) (<span class="ot">n ::</span> <span class="dt">TypeInt</span>) <span class="kw">where</span></a>
118+
<a class="sourceLine" id="cb12-2" data-line-number="2"> <span class="dt">Power</span> (<span class="ch">&#39;Dim le ma ti cu te su lu) n =</span></a>
119+
<a class="sourceLine" id="cb12-3" data-line-number="3"> <span class="ch">&#39;Dim (le*n) (ma*n) (ti*n) (cu*n) (te*n) (su*n) (lu*n)</span></a></code></pre></div>
120+
<p>Now types for dimensions can be created by combining exisiting types, much like we did for values in the previous chapter.</p>
121+
<p><strong>Exercise.</strong> Create types for velocity, area, force and impulse.</p>
122+
<p><strong>Solution.</strong></p>
123+
<div class="sourceCode" id="cb13"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb13-1" data-line-number="1"><span class="kw">type</span> <span class="dt">Velocity&#39;</span> <span class="fu">=</span> <span class="dt">Length</span> <span class="ot">`Div`</span> <span class="dt">Time</span></a>
124+
<a class="sourceLine" id="cb13-2" data-line-number="2"><span class="kw">type</span> <span class="dt">Area</span> <span class="fu">=</span> <span class="dt">Length</span> <span class="ot">`Mul`</span> <span class="dt">Length</span></a>
125+
<a class="sourceLine" id="cb13-3" data-line-number="3"><span class="kw">type</span> <span class="dt">Force</span> <span class="fu">=</span> <span class="dt">Mass</span> <span class="ot">`Mul`</span> <span class="dt">Length</span></a>
126+
<a class="sourceLine" id="cb13-4" data-line-number="4"><span class="kw">type</span> <span class="dt">Impulse</span> <span class="fu">=</span> <span class="dt">Force</span> <span class="ot">`Mul`</span> <span class="dt">Time</span></a></code></pre></div>
114127
<p>Perhaps not very exiting so far. But just wait ’til we create a data type for quantities. Then the strenghts of type-level dimensions will be clearer.</p>
115128

116129
</main>
117130

118131
<footer>
132+
<nav>
133+
<span>Previous: <a href="../Dimensions/Testing of value-level dimensions.html">Testing of value-level dimensions</a></span>
134+
<a href="../index.html">Table of contents</a>
135+
<span>Next: <a href="../Dimensions/Quantities.html">Quantities</a></span>
136+
</nav>
119137
Licensed under the GPL by the Kandidatboisen (2018)
120138
</footer>
121139
</body>

0 commit comments

Comments
 (0)