Skip to content

Commit 50816b1

Browse files
authored
Fix typos in functionally-solving-problems (learnyouahaskell#20)
* Fixed oevr typo to over * bast and lenghts typos fixed * involed typo fix
1 parent f416c08 commit 50816b1

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

docs/functionally-solving-problems.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ <h1>Functionally Solving Problems</h1>
153153
<li>Think about how we're going to represent our data in Haskell</li>
154154
<li>Figure out how to operate on that data in Haskell so that we produce at a solution</li>
155155
</ul>
156-
<p>In the RPN calculator section, we first figured out that when calculating an expression by hand, we'd keep a sort of stack in our minds and then go over the expression one item at a time. We decided to use a list of strings to represent our expression. Finally, we used a left fold to walk oevr the list of strings while keeping a stack to produce a solution.</p>
156+
<p>In the RPN calculator section, we first figured out that when calculating an expression by hand, we'd keep a sort of stack in our minds and then go over the expression one item at a time. We decided to use a list of strings to represent our expression. Finally, we used a left fold to walk over the list of strings while keeping a stack to produce a solution.</p>
157157
<p>Okay, so how would we figure out the shortest path from Heathrow to London by hand? Well, we can just sort of look at the whole picture and try to guess what the shortest path is and hopefully we'll make a guess that's right. That solution works for very small inputs, but what if we have a road that has 10,000 sections? Yikes! We also won't be able to say for certain that our solution is the optimal one, we can just sort of say that we're pretty sure.</p>
158158
<p>That's not a good solution then. Here's a simplified picture of our road system:</p>
159159
<img src="https://s3.amazonaws.com/lyah/roads_simple.png" alt="roads" class="center" width="685" height="245">
@@ -163,7 +163,7 @@ <h1>Functionally Solving Problems</h1>
163163
<div class="hintbox"><em>Maybe you're asking yourself</em>: but what about getting to <i>A2</i> by first crossing over at <i>B1</i> and then going on forward? Well, we already covered crossing from <i>B1</i> to <i>A1</i> when we were looking for the best way to <i>A1</i>, so we don't have to take that into account in the next step as well.</div>
164164
<p>Now that we have the best path to <i>A2</i> and <i>B2</i>, we can repeat this indefinitely until we reach the end. Once we've gotten the best paths for <i>A4</i> and <i>B4</i>, 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>
166-
<p>Here's a summary. To get the bast 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>
166+
<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>
167167
<p>So in essence, we keep one shortest path on the A road and one shortest path on the B road and when we reach the end, the shorter of those two is our path. We now know how to figure out the shortest path by hand. If you had enough time, paper and pencils, you could figure out the shortest path through a road system with any number of sections.</p>
168168
<p>Next step! How do we represent this road system with Haskell's data types? One way is to think of the starting points and crossroads as nodes of a graph that point to other crossroads. If we imagine that the starting points actually point to each other with a road that has a length of one, we see that every crossroads (or node) points to the node on the other side and also to the next one on its side. Except for the last nodes, they just point to the other side. </p>
169169
<pre name="code" class="haskell:hs">
@@ -182,7 +182,7 @@ <h1>Functionally Solving Problems</h1>
182182
data Section = Section { getA :: Int, getB :: Int, getC :: Int } deriving (Show)
183183
type RoadSystem = [Section]
184184
</pre>
185-
<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 lenghts of its three road parts. We introduce a type synonym as well, saying that <span class="fixed">RoadSystem</span> is a list of sections.
185+
<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.
186186
<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>
187187
<p>Our road system from Heathrow to London can now be represented like this:</p>
188188
<pre name="code" class="haskell:hs">
@@ -199,7 +199,7 @@ <h1>Functionally Solving Problems</h1>
199199
[(B,10),(C,30),(A,5),(C,20),(B,2),(B,8)]
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>
202-
<p>When doing the solution by hand, there was a step that we repeated over and over again. It involed 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 <i>A1</i> is <span class="fixed">[(B,10),(C,30)]</span> and the optimal path to <i>B1</i> 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>
202+
<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 <i>A1</i> is <span class="fixed">[(B,10),(C,30)]</span> and the optimal path to <i>B1</i> 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>
203203
<div class="hintbox"><em>Hint:</em> 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>
204204
<pre name="code" class="haskell:hs">
205205
roadStep :: (Path, Path) -&gt; Section -&gt; (Path, Path)

0 commit comments

Comments
 (0)