Skip to content

Commit a2563f0

Browse files
author
Gregory Cox
committed
Put <p> tag around contents of hintboxes
1 parent d51af06 commit a2563f0

14 files changed

+49
-43
lines changed

docs/a-fistful-of-monads.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,12 @@ <h2 id="getting-our-feet-wet-with-maybe">Getting our feet wet with Maybe</h2>
181181
monads.
182182
</p>
183183

184-
<div class="hintbox">
184+
<div class="hintbox"><p>
185185
Make sure you understand <a href="functors-applicative-functors-and-monoids.html#applicative-functors">applicatives</a> at this point. It’s good if you have a
186186
feel for how the various <span class="fixed">Applicative</span> instances work
187187
and what kind of computations they represent, because monads are nothing more
188188
than taking our existing applicative knowledge and upgrading it.
189-
</div>
189+
</p></div>
190190

191191
<p>
192192
A value of type <span class="fixed">Maybe a</span> represents a value of type
@@ -422,12 +422,12 @@ <h2 id="the-monad-type-class">The Monad type class</h2>
422422
<span class="fixed">Just</span>.
423423
</p>
424424

425-
<div class="hintbox">
425+
<div class="hintbox"><p>
426426
Just a reminder: <span class="fixed">return</span> is nothing like the
427427
<span class="fixed">return</span> that’s in most other languages. It doesn’t end
428428
function execution or anything, it just takes a normal value and puts it in a
429429
context.
430-
</div>
430+
</p></div>
431431

432432
<img src="assets/images/a-fistful-of-monads/tur2.png" class="left" width="169" height="145" alt="hmmm yaes">
433433

@@ -1487,11 +1487,11 @@ <h2 id="the-list-monad">The list monad</h2>
14871487
lists) but it does present something as its result.
14881488
</p>
14891489

1490-
<div class="hintbox">
1490+
<div class="hintbox"><p>
14911491
When you have non-deterministic values interacting, you can view their
14921492
computation as a tree where every possible result in a list represents a
14931493
separate branch.
1494-
</div>
1494+
</p></div>
14951495

14961496
<p>
14971497
Here’s the previous expression rewritten in <span class="fixed">do</span> notation:

docs/assets/css/style.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ pre.code {
8080
margin-bottom:25px;
8181
background-image:url(https://s3.amazonaws.com/lyah/note.jpg);
8282
}
83+
.hintbox > p {
84+
margin-bottom:0px;
85+
}
8386
.label {
8487
white-space:nowrap;
8588
font-family:Consolas, "Courier New", monospace;

docs/for-a-few-monads-more.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,9 @@ <h2 id="writer">Writer? I hardly know her!</h2>
219219

220220
<h3 id="monoids-to-the-rescue">Monoids to the rescue</h3>
221221

222-
<div class="hintbox">
222+
<div class="hintbox"><p>
223223
Be sure you know what <a href="functors-applicative-functors-and-monoids.html#monoids">monoids</a> are at this point! Cheers.
224-
</div>
224+
</p></div>
225225

226226
<p>
227227
Right now, <span class="fixed">applyLog</span> takes values of type
@@ -1203,7 +1203,7 @@ <h2 id="state">Tasteful stateful computations</h2>
12031203
<span class="fixed">a</span> the result of the stateful computations.
12041204
</p>
12051205

1206-
<div class="hintbox">
1206+
<div class="hintbox"><p>
12071207
Assignment in most other languages could be thought of as a stateful
12081208
computation. For instance, when we do <span class="fixed">x = 5</span> in an
12091209
imperative language, it will usually assign the value
@@ -1213,7 +1213,7 @@ <h2 id="state">Tasteful stateful computations</h2>
12131213
(that is, all the variables that have been assigned previously) and returns a
12141214
result (in this case <span class="fixed">5</span>) and a new state, which would
12151215
be all the previous variable mappings plus the newly assigned variable.
1216-
</div>
1216+
</p></div>
12171217

12181218
<p>
12191219
This stateful computation, a function that takes a state

docs/functionally-solving-problems.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ <h2 id="reverse-polish-notation-calculator">Reverse Polish notation calculator</
4040
<p>Let’s go over the expression <span class="fixed">10 4 3 + 2 * -</span> together! First we push <span class="fixed">10</span> on to the stack and the stack is now <span class="fixed">10</span>. The next item is <span class="fixed">4</span>, so we push it to the stack as well. The stack is now <span class="fixed">10, 4</span>. We do the same with <span class="fixed">3</span> and the stack is now <span class="fixed">10, 4, 3</span>. And now, we encounter an operator, namely <span class="fixed">+</span>! We pop the two top numbers from the stack (so now the stack is just <span class="fixed">10</span>), add those numbers together and push that result to the stack. The stack is now <span class="fixed">10, 7</span>. We push <span class="fixed">2</span> to the stack, the stack for now is <span class="fixed">10, 7, 2</span>. We’ve encountered an operator again, so let’s pop <span class="fixed">7</span> and <span class="fixed">2</span> off the stack, multiply them and push that result to the stack. Multiplying <span class="fixed">7</span> and <span class="fixed">2</span> produces a <span class="fixed">14</span>, so the stack we have now is <span class="fixed">10, 14</span>. Finally, there’s a <span class="fixed">-</span>. We pop <span class="fixed">10</span> and <span class="fixed">14</span> from the stack, subtract <span class="fixed">14</span> from <span class="fixed">10</span> and push that back. The number on the stack is now <span class="fixed">-4</span> and because there are no more numbers or operators in our expression, that’s our result!</p>
4141
<p>Now that we know how we’d calculate any RPN expression by hand, let’s think about how we could make a Haskell function that takes as its parameter a string that contains a RPN expression, like <span class="fixed">"10 4 3 + 2 * -"</span> and gives us back its result.</p>
4242
<p>What would the type of that function be? We want it to take a string as a parameter and produce a number as its result. So it will probably be something like <span class="fixed">solveRPN :: (Num a) =&gt; String -&gt; a</span>.</p>
43-
<div class="hintbox"><strong>Protip:</strong> it really helps to first think what the type declaration of a function should be before concerning ourselves with the implementation and then write it down. In Haskell, a function’s type declaration tells us a whole lot about the function, due to the very strong type system.</div>
43+
<div class="hintbox"><p><strong>Protip:</strong> it really helps to first think what the type declaration of a function should be before concerning ourselves with the implementation and then write it down. In Haskell, a function’s type declaration tells us a whole lot about the function, due to the very strong type system.</p></div>
4444
<img src="assets/images/functionally-solving-problems/calculator.png" class="left" width="220" height="190" alt="HA HA HA">
4545
<p>Cool. When implementing a solution to a problem in Haskell, it’s also good to think back on how you did it by hand and maybe try to see if you can gain any insight from that. Here we see that we treated every number or operator that was separated by a space as a single item. So it might help us if we start by breaking a string like <span class="fixed">"10 4 3 + 2 * -"</span> into a list of items like <span class="fixed">["10","4","3","+","2","*","-"]</span>.</p>
4646
<p>Next up, what did we do with that list of items in our head? We went over it from left to right and kept a stack as we did that. Does the previous sentence remind you of anything? Remember, in the section about <a href="higher-order-functions.html#folds">folds</a>, we said that pretty much any function where you traverse a list from left to right or right to left one element by element and build up (accumulate) some result (whether it’s a number, a list, a stack, whatever) can be implemented with a fold.</p>
@@ -160,7 +160,7 @@ <h2 id="heathrow-to-london">Heathrow to London</h2>
160160
<p>Alright, can you figure out what the shortest path to the first crossroads (the first blue dot on A, marked <em>A1</em>) on road A is? That’s pretty trivial. We just see if it’s shorter to go directly forward on A or if it’s shorter to go forward on B and then cross over. Obviously, it’s cheaper to go forward via B and then cross over because that takes 40 minutes, whereas going directly via A takes 50 minutes. What about crossroads <em>B1</em>? Same thing. We see that it’s a lot cheaper to just go directly via B (incurring a cost of 10 minutes), because going via A and then crossing over would take us a whole 80 minutes!</p>
161161
<p>Now we know what the cheapest path to <em>A1</em> is (go via B and then cross over, so we’ll say that’s <span class="fixed">B, C</span> with a cost of 40) and we know what the cheapest path to <em>B1</em> is (go directly via B, so that’s just <span class="fixed">B</span>, going at 10). Does this knowledge help us at all if we want to know the cheapest path to the next crossroads on both main roads? Gee golly, it sure does!</p>
162162
<p>Let’s see what the shortest path to <em>A2</em> would be. To get to <em>A2</em>, we’ll either go directly to <em>A2</em> from <em>A1</em> or we’ll go forward from <em>B1</em> and then cross over (remember, we can only move forward or cross to the other side). And because we know the cost to <em>A1</em> and <em>B1</em>, we can easily figure out what the best path to <em>A2</em> is. It costs 40 to get to <em>A1</em> and then 5 to get from <em>A1</em> to <em>A2</em>, so that’s <span class="fixed">B, C, A</span> for a cost of 45. It costs only 10 to get to <em>B1</em>, but then it would take an additional 110 minutes to go to <em>B2</em> and then cross over! So obviously, the cheapest path to <em>A2</em> is <span class="fixed">B, C, A</span>. In the same way, the cheapest way to <em>B2</em> is to go forward from <em>A1</em> and then cross over.</p>
163-
<div class="hintbox"><strong>Maybe you’re asking yourself</strong>: but what about getting to <em>A2</em> by first crossing over at <em>B1</em> and then going on forward? Well, we already covered crossing from <em>B1</em> to <em>A1</em> when we were looking for the best way to <em>A1</em>, so we don’t have to take that into account in the next step as well.</div>
163+
<div class="hintbox"><p><strong>Maybe you’re asking yourself</strong>: but what about getting to <em>A2</em> by first crossing over at <em>B1</em> and then going on forward? Well, we already covered crossing from <em>B1</em> to <em>A1</em> when we were looking for the best way to <em>A1</em>, so we don’t have to take that into account in the next step as well.</p></div>
164164
<p>Now that we have the best path to <em>A2</em> and <em>B2</em>, we can repeat this indefinitely until we reach the end. Once we’ve gotten the best paths for <em>A4</em> and <em>B4</em>, the one that’s cheaper is the optimal path!</p>
165165
<p>So in essence, for the second section, we just repeat the step we did at first, only we take into account what the previous best paths on A and B. We could say that we also took into account the best paths on A and on B in the first step, only they were both empty paths with a cost of 0.</p>
166166
<p>Here’s a summary. To get the best path from Heathrow to London, we do this: first we see what the best path to the next crossroads on main road A is. The two options are going directly forward or starting at the opposite road, going forward and then crossing over. We remember the cost and the path. We use the same method to see what the best path to the next crossroads on main road B is and remember that. Then, we see if the path to the next crossroads on A is cheaper if we go from the previous A crossroads or if we go from the previous B crossroads and then cross over. We remember the cheaper path and then we do the same for the crossroads opposite of it. We do this for every section until we reach the end. Once we’ve reached the end, the cheapest of the two paths that we have is our optimal path!</p>
@@ -183,7 +183,7 @@ <h2 id="heathrow-to-london">Heathrow to London</h2>
183183
type RoadSystem = [Section]
184184
</pre>
185185
<p>This is pretty much perfect! It’s as simple as it goes and I have a feeling it’ll work perfectly for implementing our solution. <span class="fixed">Section</span> is a simple algebraic data type that holds three integers for the lengths of its three road parts. We introduce a type synonym as well, saying that <span class="fixed">RoadSystem</span> is a list of sections.</p>
186-
<div class="hintbox">We could also use a triple of <span class="fixed">(Int, Int, Int)</span> to represent a road section. Using tuples instead of making your own algebraic data types is good for some small localized stuff, but it’s usually better to make a new type for things like this. It gives the type system more information about what’s what. We can use <span class="fixed">(Int, Int, Int)</span> to represent a road section or a vector in 3D space and we can operate on those two, but that allows us to mix them up. If we use <span class="fixed">Section</span> and <span class="fixed">Vector</span> data types, then we can’t accidentally add a vector to a section of a road system.</div>
186+
<div class="hintbox"><p>We could also use a triple of <span class="fixed">(Int, Int, Int)</span> to represent a road section. Using tuples instead of making your own algebraic data types is good for some small localized stuff, but it’s usually better to make a new type for things like this. It gives the type system more information about what’s what. We can use <span class="fixed">(Int, Int, Int)</span> to represent a road section or a vector in 3D space and we can operate on those two, but that allows us to mix them up. If we use <span class="fixed">Section</span> and <span class="fixed">Vector</span> data types, then we can’t accidentally add a vector to a section of a road system.</p></div>
187187
<p>Our road system from Heathrow to London can now be represented like this:</p>
188188
<pre name="code" class="haskell:hs">
189189
heathrowToLondon :: RoadSystem
@@ -200,7 +200,7 @@ <h2 id="heathrow-to-london">Heathrow to London</h2>
200200
</pre>
201201
<p>We’re going to have to walk over the list with the sections from left to right and keep the optimal path on A and optimal path on B as we go along. We’ll accumulate the best path as we walk over the list, left to right. What does that sound like? Ding, ding, ding! That’s right, A LEFT FOLD!</p>
202202
<p>When doing the solution by hand, there was a step that we repeated over and over again. It involved checking the optimal paths on A and B so far and the current section to produce the new optimal paths on A and B. For instance, at the beginning the optimal paths were <span class="fixed">[]</span> and <span class="fixed">[]</span> for A and B respectively. We examined the section <span class="fixed">Section 50 10 30</span> and concluded that the new optimal path to <em>A1</em> is <span class="fixed">[(B,10),(C,30)]</span> and the optimal path to <em>B1</em> is <span class="fixed">[(B,10)]</span>. If you look at this step as a function, it takes a pair of paths and a section and produces a new pair of paths. The type is <span class="fixed">(Path, Path) -&gt; Section -&gt; (Path, Path)</span>. Let’s go ahead and implement this function, because it’s bound to be useful.</p>
203-
<div class="hintbox"><strong>Hint:</strong> it will be useful because <span class="fixed">(Path, Path) -&gt; Section -&gt; (Path, Path)</span> can be used as the binary function for a left fold, which has to have a type of <span class="fixed">a -&gt; b -&gt; a</span></div>
203+
<div class="hintbox"><p><strong>Hint:</strong> it will be useful because <span class="fixed">(Path, Path) -&gt; Section -&gt; (Path, Path)</span> can be used as the binary function for a left fold, which has to have a type of <span class="fixed">a -&gt; b -&gt; a</span></p></div>
204204
<pre name="code" class="haskell:hs">
205205
roadStep :: (Path, Path) -&gt; Section -&gt; (Path, Path)
206206
roadStep (pathA, pathB) (Section a b c) =
@@ -228,7 +228,7 @@ <h2 id="heathrow-to-london">Heathrow to London</h2>
228228
([(C,30),(B,10)],[(B,10)])
229229
</pre>
230230
<p>Remember, the paths are reversed, so read them from right to left. From this we can read that the best path to the next A is to start on B and then cross over to A and that the best path to the next B is to just go directly forward from the starting point at B.</p>
231-
<div class="hintbox"><strong>Optimization tip:</strong> when we do <span class="fixed">priceA = sum $ map snd pathA</span>, we’re calculating the price from the path on every step. We wouldn’t have to do that if we implemented <span class="fixed">roadStep</span> as a <span class="fixed">(Path, Path, Int, Int) -&gt; Section -&gt; (Path, Path, Int, Int)</span> function where the integers represent the best price on A and B.</div>
231+
<div class="hintbox"><p><strong>Optimization tip:</strong> when we do <span class="fixed">priceA = sum $ map snd pathA</span>, we’re calculating the price from the path on every step. We wouldn’t have to do that if we implemented <span class="fixed">roadStep</span> as a <span class="fixed">(Path, Path, Int, Int) -&gt; Section -&gt; (Path, Path, Int, Int)</span> function where the integers represent the best price on A and B.</p></div>
232232
<p>Now that we have a function that takes a pair of paths and a section and produces a new optimal path, we can just easily do a left fold over a list of sections. <span class="fixed">roadStep</span> is called with <span class="fixed">([],[])</span> and the first section and returns a pair of optimal paths to that section. Then, it’s called with that pair of paths and the next section and so on. When we’ve walked over all the sections, we’re left with a pair of optimal paths and the shorter of them is our answer. With this in mind, we can implement <span class="fixed">optimalPath</span>.</p>
233233
<pre name="code" class="haskell:hs">
234234
optimalPath :: RoadSystem -&gt; Path

0 commit comments

Comments
 (0)