Skip to content

Commit 4f4c044

Browse files
committed
Style exercise/solutions to make more distinct from surroundings
1 parent 15570ba commit 4f4c044

File tree

7 files changed

+172
-22
lines changed

7 files changed

+172
-22
lines changed

Book/style.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,19 @@ blockquote {
126126
border-left: 3px solid #BABABA;
127127
}
128128

129+
details {
130+
margin-bottom: 30px;
131+
}
132+
133+
/* Exercise solutions / spoilers */
134+
details > div {
135+
margin-top: 10px;
136+
margin-left: 30px;
137+
padding: 10px 20px;
138+
border-radius: 10px;
139+
background-color: #fcfbf0;
140+
}
141+
129142
/* VVVV GENERATED BY PANDOC BELOW VVV */
130143

131144
code {

Physics/src/Calculus/DifferentialCalc.lhs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,18 @@ And the limit
306306

307307
$$\lim_{x \to 0} \frac{sin x}{x} = 1$$
308308

309-
which can be proved using the unit circle and squeeze theorem, but we
310-
won't do that here.
309+
the proof of which is left as an exercise to the reader
310+
311+
**Exercise.** Prove the limit $\lim_{x \to 0} \frac{sin x}{x} = 1$
312+
313+
<details>
314+
<summary>**Hint**</summary>
315+
<div>
316+
317+
This limit can be proven using the [unit circle](https://en.wikipedia.org/wiki/Unit_circle) and [squeeze theorem](https://en.wikipedia.org/wiki/Squeeze_theorem)
318+
319+
</div>
320+
</details>
311321

312322
Then, the differentiation
313323

@@ -328,7 +338,11 @@ Again, trivial definition in Haskell
328338

329339
> derive Sin = Cos
330340

331-
I'll leave the proving of the rest of the implementations as an exercise to you, the reader.
341+
**Exercise.** Derive the rest of the cases using the definition of the derivative
342+
343+
<details>
344+
<summary>**Solution**</summary>
345+
<div>
332346

333347
> derive Exp = Exp
334348
> derive Log = Const 1 :/ Id
@@ -338,7 +352,8 @@ I'll leave the proving of the rest of the implementations as an exercise to you,
338352
> derive (f :- g) = derive f :- derive g
339353
> derive (f :* g) = derive f :* g :+ f :* derive g
340354
> derive (f :/ g) = (derive f :* g :- f :* derive g) :/ (g:^(Const 2))
341-
> derive (f :^ g) = f:^(g :- Const 1) :* (g :* derive f :+ f :* (Log :. f) :* derive g)
355+
> derive (f :^ g) = f:^(g :- Const 1)
356+
> :* (g :* derive f :+ f :* (Log :. f) :* derive g)
342357
> derive Id = Const 1
343358
> derive (Const _) = Const 0
344359
> derive (f :. g) = derive g :* (derive f :. g)
@@ -352,7 +367,8 @@ for integral is *Antiderivative*...
352367

353368
> derive (I c f) = f
354369

355-
370+
</div>
371+
</details>
356372

357373
Keep it simple
358374
----------------------------------------------------------------------
@@ -452,6 +468,21 @@ Exponentiation is not commutative, and further has no (two-sided) identity eleme
452468
> (f', Const 1) -> f'
453469
> (f', g') -> f' :^ g'
454470

471+
**Exercises.** Look up (or prove by yourself) more identities (of
472+
expressions, not identity elements) for exponentiation and implement
473+
them.
474+
475+
<details>
476+
<summary>**Solution**</summary>
477+
<div>
478+
479+
For example, there is the identity of negative exponents. For any integer $n$ and nonzero $b$
480+
481+
$$b^{-n} = \frac{1}{b^n}$$
482+
483+
</div>
484+
</details>
485+
455486
Intuitively, the identity function is the identity element for function composition
456487

457488
> simplify (f :. g) = case (simplify f, simplify g) of
@@ -473,3 +504,5 @@ With this new function, many expressions become much more readable!
473504
< (cos + (2 * id))
474505

475506
A sight for sore eyes!
507+
508+
**Exercise.** Think of more ways an expression can be "simplified", and add your cases to the implementation.

Physics/src/Calculus/IntegralCalc.lhs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,19 @@ which at least implies that we can use polynomials.
396396
> (Id, Const c) -> Id:^(Const (c+1)) :/ Const (c+1)
397397
> (_, _) -> error "Can't integrate integrals like that!"
398398

399+
**Exercise.** Find more rules of integrating exponentials and add to
400+
the implementation.
401+
402+
<details>
403+
<summary>**Solution**</summary>
404+
<div>
405+
406+
Wikipedia has [a nice list of integrals of exponentials](https://en.wikipedia.org/wiki/List_of_integrals_of_exponential_functions)
407+
408+
</div>
409+
</details>
410+
411+
399412
Integration of function composition is, simply said, somewhat
400413
complicated. The technique to use is called "integration by
401414
substitution", and is something like a reverse of the chain-rule of

Physics/src/Dimensions/Quantity.lhs

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,16 @@ Note that the `Quantity` data type has both value-level and type-level dimension
106106
107107
TODO: What is the purpose (semantics, intended meaning or use) of Quantity'?
108108
109-
**Solution.**
109+
<details>
110+
<summary>**Solution**</summary>
111+
<div>
110112
111113
< data Quantity' (d1 :: T.Dim) (d2 :: T.Dim) where
112114
< Quantity' :: Rational -> Rational -> Quantity' d1 d2
113115
116+
</div>
117+
</details>
118+
114119
A taste of types
115120
----------------
116121
@@ -141,7 +146,14 @@ The type has the following interpretation: two values of type `Quantity dx v` is
141146
142147
![Are you a cowboy?](Cowboy.png){.float-img-right}
143148
144-
**Solution.** Hold on cowboy! Not so fast. We'll come back later to subtraction and division, so check your solution then.
149+
<details>
150+
<summary>**Solution**</summary>
151+
<div>
152+
153+
Hold on cowboy! Not so fast. We'll come back later to subtraction and division, so check your solution then.
154+
155+
</div>
156+
</details>
145157
146158
Now on to some example values and types.
147159
@@ -188,7 +200,9 @@ If the dimensions had been value-level only, this error would go undetected unti
188200
189201
**Exercise.** What is the volume of a cuboid with sides $1.2\ m$, $0.4\ m$ and $1.9\ m$? Create values for the involved quantities. Use `Float` instead of `Double`.
190202
191-
**Solution.**
203+
<details>
204+
<summary>**Solution**</summary>
205+
<div>
192206
193207
> side1 :: Quantity Length Float
194208
> side1 = Quantity V.length 1.2
@@ -204,6 +218,9 @@ If the dimensions had been value-level only, this error would go undetected unti
204218
> volume :: Quantity Volume Float
205219
> volume = quantityMul side1 (quantityMul side2 side3)
206220
221+
</div>
222+
</details>
223+
207224
Pretty-printer
208225
--------------
209226
@@ -228,7 +245,9 @@ It's useful to be able to compare quantities. Perhaps one wants to know which of
228245
229246
**Exercise.** Make `Quantity` an instance of `Ord`.
230247
231-
**Solution.**
248+
<details>
249+
<summary>**Solution**</summary>
250+
<div>
232251
233252
> quantityCompare :: (Ord v) => Quantity d v ->
234253
> Quantity d v -> Ordering
@@ -238,6 +257,9 @@ It's useful to be able to compare quantities. Perhaps one wants to know which of
238257
> instance (Ord v) => Ord (Quantity d v) where
239258
> compare = quantityCompare
240259
260+
</div>
261+
</details>
262+
241263
We often use `Double` as the value holding type. Doing exact comparsions isn't always possible to due rounding errors. Therefore, we'll create a `~=` function for testing if two quantities are almost equal.
242264
243265
> infixl 4 ~=
@@ -326,7 +348,9 @@ However, operations with only scalars (type `One`) has types compatible with `Nu
326348
327349
**Exercise.** `Quantity One` has compatible types. Make it an instance of `Num`, `Fractional`, `Floating` and `Functor`.
328350
329-
**Solution.**
351+
<details>
352+
<summary>**Solution**</summary>
353+
<div>
330354
331355
> instance (Num v) => Num (Quantity One v) where
332356
> (+) = (+#)
@@ -358,6 +382,9 @@ However, operations with only scalars (type `One`) has types compatible with `Nu
358382
> instance Functor (Quantity One) where
359383
> fmap = qmap
360384
385+
</div>
386+
</details>
387+
361388
Syntactic sugar
362389
---------------
363390
@@ -388,7 +415,9 @@ TODO: Please use "1" instead of "0" in all the dimensions. That signifies an amo
388415
389416
**Exercise.** Do the rest.
390417
391-
**Solution.**
418+
<details>
419+
<summary>**Solution**</summary>
420+
<div>
392421
393422
> current :: (Num v) => Quantity Current v
394423
> current = Quantity V.current 0
@@ -405,6 +434,9 @@ TODO: Please use "1" instead of "0" in all the dimensions. That signifies an amo
405434
> one :: (Num v) => Quantity One v
406435
> one = Quantity V.one 0
407436
437+
</div>
438+
</details>
439+
408440
And now the sugar.
409441
410442
TODO: Please multiply the values instead of throwing them away. I'm pretty sure (#) should behave as "scale" of a vector space. So that (x#(y#z)) == ((x*y)#z).
@@ -460,14 +492,19 @@ Just for convenience sake we'll define a bunch of common composite dimensions. E
460492
461493
**Exericse.** Define pre-made values for velocity, acceleration, force, momentum and energy.
462494
463-
**Solution.**
495+
<details>
496+
<summary>**Solution**</summary>
497+
<div>
464498
465499
> velocity = length /# time
466500
> acceleration = velocity /# time
467501
> force = mass *# acceleration
468502
> momentum = force *# time
469503
> energy = force *# length
470504
505+
</div>
506+
</details>
507+
471508
---
472509
473510
Alternative sugar with support for units
@@ -481,7 +518,9 @@ Alternative sugar with support for units
481518
< ghci> distance
482519
< 8046.72 m
483520
484-
**Solution.**
521+
<details>
522+
<summary>**Solution**</summary>
523+
<div>
485524
486525
> metre = 1 # length
487526
> kilometre = 1000 # length
@@ -504,6 +543,9 @@ Notice how the value is multiplied with the "base value" of the unit. This funct
504543
< ghci> velocity1 +# velocity2
505544
< 67.77 m/s
506545
546+
</div>
547+
</details>
548+
507549
A physics example
508550
-----------------
509551

Physics/src/Dimensions/TypeLevel.lhs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,18 @@ This may sound confusing, but the point of this will become clear over time. Let
8989

9090
**Exercise.** Create types for velocity, acceleration and the scalar.
9191

92-
**Solution.**
92+
<details>
93+
<summary>**Solution**</summary>
94+
<div>
9395

9496
> type Velocity = 'Dim Pos1 Zero Neg1 Zero Zero Zero Zero
9597
> type Acceleration = 'Dim Pos1 Zero Neg2 Zero Zero Zero Zero
9698

9799
> type One = 'Dim Zero Zero Zero Zero Zero Zero Zero
98100

101+
</div>
102+
</details>
103+
99104
Multiplication and division
100105
---------------------------
101106

@@ -113,31 +118,46 @@ Let's implement multiplication and division on the type-level. After such an ope
113118

114119
**Exercise.** As you would suspect, division is very similar, so why don't you try 'n implement it yourself?
115120

116-
**Solution.**
121+
<details>
122+
<summary>**Solution**</summary>
123+
<div>
117124

118125
> type family Div (d1 :: Dim) (d2 :: Dim) where
119126
> Div ('Dim le1 ma1 ti1 cu1 te1 su1 lu1)
120127
> ('Dim le2 ma2 ti2 cu2 te2 su2 lu2) =
121128
> 'Dim (le1-le2) (ma1-ma2) (ti1-ti2) (cu1-cu2)
122129
> (te1-te2) (su1-su2) (lu1-lu2)
123130

131+
</div>
132+
</details>
133+
124134
**Exercise.** Implement a type-level function for raising a dimension to the power of some integer.
125135

126-
**Solution.**
136+
<details>
137+
<summary>**Solution**</summary>
138+
<div>
127139

128140
< type family Power (d :: Dim) (n :: TypeInt) where
129141
< Power ('Dim le ma ti cu te su lu) n =
130142
< 'Dim (le*n) (ma*n) (ti*n) (cu*n) (te*n) (su*n) (lu*n)
131143

144+
</div>
145+
</details>
146+
132147
Now types for dimensions can be created by combining exisiting types, much like we did for values in the previous chapter.
133148

134149
**Exercise.** Create types for velocity, area, force and impulse.
135150

136-
**Solution.**
151+
<details>
152+
<summary>**Solution**</summary>
153+
<div>
137154

138155
> type Velocity' = Length `Div` Time
139156
> type Area = Length `Mul` Length
140157
> type Force = Mass `Mul` Length
141158
> type Impulse = Force `Mul` Time
142159

160+
</div>
161+
</details>
162+
143163
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)