Skip to content

Commit 7a7cb92

Browse files
author
Oskar Lundström
committed
Merge av intro
2 parents d30a374 + 9ad0434 commit 7a7cb92

File tree

13 files changed

+393
-402
lines changed

13 files changed

+393
-402
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/Instruktioner.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
# Pandoc
1515

16-
Komilera med ` pandoc FILNAMN.lhs -f markdown+lhs -t html -o FILNAMN.html -s --mathjax`.
16+
Komilera med `pandoc FILNAMN.lhs -f markdown+lhs -t html -o FILNAMN.html -s --mathjax`.
1717

1818
# Python
1919

2.67 KB
Loading

Physics/src/Dimensions/Intro.lhs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ The dimension of a quantity is often implicitly understood given its unit. If I
1616

1717
There are 7 *base dimensions*, each with a corresponding SI-unit.
1818

19-
TODO: In my browser the list and the image components don't line up. I think you will need to split into seven images.
20-
21-
![The 7 base dimensions](Base_dimensions.png){.float-img-right}
19+
![](Base_dimensions.png "The 7 base dimensions")
2220

2321
- Length (metre)
2422
- Mass (kilogram)

Physics/src/Dimensions/Mole.png

4.07 KB
Loading

Physics/src/Dimensions/Quantity.lhs

Lines changed: 218 additions & 192 deletions
Large diffs are not rendered by default.

Physics/src/Dimensions/Quantity/Test.lhs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Testing of Quantity
33
===================
44

5+
\ignore{
6+
57
> {-# LANGUAGE DataKinds #-}
68
> {-# LANGUAGE GADTs #-}
79
> {-# LANGUAGE KindSignatures #-}
@@ -11,11 +13,23 @@ Testing of Quantity
1113
> {-# LANGUAGE FlexibleInstances #-}
1214
> {-# LANGUAGE TypeSynonymInstances #-}
1315

16+
}
17+
1418
> module Dimensions.Quantity.Test
1519
> ( runTests
1620
> )
1721
> where
1822

23+
24+
< {-# LANGUAGE DataKinds #-}
25+
< {-# LANGUAGE GADTs #-}
26+
< {-# LANGUAGE KindSignatures #-}
27+
< {-# LANGUAGE TypeFamilies #-}
28+
< {-# LANGUAGE UndecidableInstances #-}
29+
< {-# LANGUAGE TypeOperators #-}
30+
< {-# LANGUAGE FlexibleInstances #-}
31+
< {-# LANGUAGE TypeSynonymInstances #-}
32+
1933
> import Prelude hiding (length, div)
2034
> import Test.QuickCheck
2135

@@ -36,9 +50,9 @@ First we need an `Arbitrary` instance for `Quantity d val`. For `d` we'll mostly
3650
A generator for an arbitrary dimension.
3751

3852
> genQuantity :: Quantity d Double -> Gen (Q d)
39-
> genQuantity sugar = do
53+
> genQuantity quantity = do
4054
> value <- arbitrary
41-
> return (value # sugar)
55+
> return (value # quantity)
4256

4357
And now we make `Arbitrary` instances of arbitrary selected dimensions in the `Quantity`s.
4458

@@ -57,7 +71,7 @@ And now we make `Arbitrary` instances of arbitrary selected dimensions in the `Q
5771
Testing arithmetic properties
5872
-----------------------------
5973

60-
One regular numbers, and hence too on quantites with their dimensions, a bunch of properties should hold. The things we test here are
74+
On regular numbers, and hence too on quantites with their dimensions, a bunch of properties should hold. The things we test here are
6175

6276
- Addition commutative
6377
- Addition associative
@@ -69,20 +83,14 @@ One regular numbers, and hence too on quantites with their dimensions, a bunch o
6983
- Subtraction and addition cancel each other out
7084
- Division and multiplication cancel each other out
7185
- Pythagoran trigonometric identity
72-
- The sugar doesn't care about input value
7386

7487
Let's start!
7588

7689
We could write the type signatures in a general way like
7790

7891
< prop_addCom :: Q d -> Q d -> Bool
7992

80-
But we won't do that for two reasons.
81-
82-
1. QuickCheck needs concrete types in order to work. So we would have to do a bunch of specialization anyway. And even if we begin with a general signature, we can't cover all cases since there are infinitly many dimensions.
83-
2. TODO: Går inte för vissa fall, t.ex.
84-
85-
< Couldn't match type `Mul d (Mul d d)' with `Mul (Mul d d) d'
93+
But we won't do that since QuickCheck needs concrete types in order to work. So we would have to do a bunch of specialization anyway. And even if we begin with a general signature, we can't cover all cases since there are infinitly many dimensions.
8694

8795
Instead we'll pick some arbitrary dimensions that have an `Arbitrary` instance.
8896

@@ -98,7 +106,6 @@ Instead we'll pick some arbitrary dimensions that have an `Arbitrary` instance.
98106
> prop_addId :: Q Time -> Bool
99107
> prop_addId a = zero +# a ~= a
100108
> where
101-
> -- `zero` will, thanks to the versatile suger, have > -- the same dimension as `a`.
102109
> zero = 0 # a
103110

104111
> -- a * b = b * a
@@ -133,33 +140,24 @@ Instead we'll pick some arbitrary dimensions that have an `Arbitrary` instance.
133140
> prop_pythagoranIdentity a = sinq a *# sinq a +#
134141
> cosq a *# cosq a ~= (1 # one)
135142

136-
> prop_sugar :: Double -> Q Length -> Q Length -> Bool
137-
> prop_sugar v a b = v # a ~= v # b
143+
144+
\ignore{
138145

139146
Integrating tests with Stack
140147
----------------------------
141148

142149
> runTests :: IO ()
143150
> runTests = do
144-
> putStrLn "Dimensions quantity: Addition commutative"
145151
> quickCheck prop_addCom
146-
> putStrLn "Dimensions quantity: Addition associative"
147152
> quickCheck prop_addAss
148-
> putStrLn "Dimensions quantity: Zero is identity for addition"
149153
> quickCheck prop_addId
150-
> putStrLn "Dimensions quantity: Multiplication commutative"
151154
> quickCheck prop_mulCom
152-
> putStrLn "Dimensions quantity: Multiplication associative"
153155
> quickCheck prop_mulAss
154-
> putStrLn "Dimensions quantity: One is identity for multiplication"
155156
> quickCheck prop_mulId
156-
> putStrLn "Dimensions quantity: Addition distributes over multiplication"
157157
> quickCheck prop_addDistOverMul
158-
> putStrLn "Dimensions quantity: Subtraction and addition cancel each other out"
159158
> quickCheck prop_addSubCancel
160-
> putStrLn "Dimensions quantity: Division and multiplication cancel each other out"
161159
> quickCheck prop_mulDivCancel
162-
> putStrLn "Dimensions quantity: Pythagoran trigonometric identity"
163160
> quickCheck prop_pythagoranIdentity
164-
> putStrLn "Dimensions quantity: Sugar is correct"
165-
> quickCheck prop_sugar
161+
> putStrLn "Dimensions Quantity tests passed!"
162+
163+
}
5.66 KB
Loading
3.61 KB
Loading

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)