Skip to content

Commit 39f3c22

Browse files
author
Oskar Lundström
committed
Centrerade bilder och ändrad ordning i type-level dims
1 parent 26f6888 commit 39f3c22

File tree

2 files changed

+39
-22
lines changed

2 files changed

+39
-22
lines changed

Book/style.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ div#toc ol > li > ul {
9999
float: left;
100100
margin-right: 10px;
101101
}
102+
.img-center {
103+
display: block;
104+
margin-left: auto;
105+
margin-right: auto;
106+
width: 100%;
107+
}
102108

103109
figcaption {
104110
font-size: 70%;

Physics/src/Dimensions/TypeLevel.lhs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,7 @@
22
Type-level dimensions
33
=====================
44

5-
We will now implement *type-level* dimensions. What is type-level? Programs (in Haskell) normally operatate on (e.g. add) values (e.g. `1` and `2`). This is on *value-level*. Now we'll do the same thing but on *type-level*, that is, perform operations on types.
6-
7-
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.
8-
9-
![Adding lengths is OK. Adding lengths and areas is not OK.](Lengths_and_area.png)
10-
11-
This implemention is very similar to the value-level one. It would be possible to only have one implementation by using `Data.Proxy`. But it would be trickier. This way is lengthier but easier to understand.
12-
13-
To be able to do type-level programming, we'll need a nice stash of GHC-extensions.
5+
\ignore{
146

157
> {-# LANGUAGE DataKinds #-}
168
> {-# LANGUAGE GADTs #-}
@@ -19,7 +11,7 @@ To be able to do type-level programming, we'll need a nice stash of GHC-extensio
1911
> {-# LANGUAGE UndecidableInstances #-}
2012
> {-# LANGUAGE TypeOperators #-}
2113

22-
See the end of the next chapter to read what they do.
14+
}
2315

2416
> module Dimensions.TypeLevel
2517
> ( Dim(..)
@@ -35,6 +27,25 @@ See the end of the next chapter to read what they do.
3527
> , One
3628
> ) where
3729

30+
We will now implement *type-level* dimensions. What is type-level? Programs (in Haskell) normally operatate on (e.g. add) values (e.g. `1` and `2`). This is on *value-level*. Now we'll do the same thing but on *type-level*, that is, perform operations on types.
31+
32+
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.
33+
34+
![](Lengths_and_area.png "Adding lengths is OK. Adding lengths and areas is not OK."){.img-center}
35+
36+
This implemention is very similar to the value-level one. It would be possible to only have one implementation by using `Data.Proxy`. But it would be trickier. This way is lengthier but easier to understand.
37+
38+
To be able to do type-level programming, we'll need a nice stash of GHC-extensions.
39+
40+
< {-# LANGUAGE DataKinds #-}
41+
< {-# LANGUAGE GADTs #-}
42+
< {-# LANGUAGE KindSignatures #-}
43+
< {-# LANGUAGE TypeFamilies #-}
44+
< {-# LANGUAGE UndecidableInstances #-}
45+
< {-# LANGUAGE TypeOperators #-}
46+
47+
See the end of the next chapter to read what they do.
48+
3849
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.
3950

4051
> import Numeric.NumType.DK.Integers
@@ -87,7 +98,7 @@ This may sound confusing, but the point of this will become clear over time. Let
8798

8899
`Pos1`, `Neg1` and so on corresponds to `1` and `-1` in the imported package, which operates on type-level integers.
89100

90-
**Exercise.** Create types for velocity, acceleration and the scalar.
101+
**Exercise** Create types for velocity, acceleration and the scalar.
91102

92103
<details>
93104
<summary>**Solution**</summary>
@@ -98,8 +109,8 @@ This may sound confusing, but the point of this will become clear over time. Let
98109

99110
> type One = 'Dim Zero Zero Zero Zero Zero Zero Zero
100111

101-
</div>
102-
</details>
112+
</div>
113+
</details>
103114

104115
Multiplication and division
105116
---------------------------
@@ -116,7 +127,7 @@ Let's implement multiplication and division on the type-level. After such an ope
116127
- `Mul` is the name of the function.
117128
- `d1 :: Dim` is read as "the *type* `d1` has *kind* `Dim`".
118129

119-
**Exercise.** As you would suspect, division is very similar, so why don't you try 'n implement it yourself?
130+
**Exercise** As you would suspect, division is very similar, so why don't you try 'n implement it yourself?
120131

121132
<details>
122133
<summary>**Solution**</summary>
@@ -128,10 +139,10 @@ Let's implement multiplication and division on the type-level. After such an ope
128139
> 'Dim (le1-le2) (ma1-ma2) (ti1-ti2) (cu1-cu2)
129140
> (te1-te2) (su1-su2) (lu1-lu2)
130141

131-
</div>
132-
</details>
142+
</div>
143+
</details>
133144

134-
**Exercise.** Implement a type-level function for raising a dimension to the power of some integer.
145+
**Exercise** Implement a type-level function for raising a dimension to the power of some integer.
135146

136147
<details>
137148
<summary>**Solution**</summary>
@@ -141,12 +152,12 @@ Let's implement multiplication and division on the type-level. After such an ope
141152
< Power ('Dim le ma ti cu te su lu) n =
142153
< 'Dim (le*n) (ma*n) (ti*n) (cu*n) (te*n) (su*n) (lu*n)
143154

144-
</div>
145-
</details>
155+
</div>
156+
</details>
146157

147158
Now types for dimensions can be created by combining exisiting types, much like we did for values in the previous chapter.
148159

149-
**Exercise.** Create types for velocity, area, force and impulse.
160+
**Exercise** Create types for velocity, area, force and impulse.
150161

151162
<details>
152163
<summary>**Solution**</summary>
@@ -157,7 +168,7 @@ Now types for dimensions can be created by combining exisiting types, much like
157168
> type Force = Mass `Mul` Length
158169
> type Impulse = Force `Mul` Time
159170

160-
</div>
161-
</details>
171+
</div>
172+
</details>
162173

163174
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.

0 commit comments

Comments
 (0)