Skip to content

Commit d2e20cc

Browse files
authored
Update/fix some links (#14)
* Update some links * Update Haskell Platform link
1 parent 2d9e195 commit d2e20cc

File tree

6 files changed

+8
-8
lines changed

6 files changed

+8
-8
lines changed

docs/faq.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ <h2>Can I put this tutorial on my site or change it or whatever?</h2>
2222
<p>Sure, it's licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/" rel="nofollow">creative commons</a> license, so you can share and change this, as long as you do it with a smile on your face and for non-commercial purposes.</p>
2323
<h2>Do you recommend any other Haskell reading material?</h2>
2424
<p>There are loads of awesome tutorials out there, but I'd just like to point out how great <a href="http://book.realworldhaskell.org/read/" rel="nofollow">Real World Haskell</a> is. It's really great. I feel it complements this tutorial nicely. This tutorial focuses mainly on using simple examples to ease beginners into learning Haskell, whereas Real World Haskell really shows you how to do useful stuff with it.</p>
25-
<p>Another great Haskell resource is <a href="http://tryhaskell.org" rel="nofollow">Try Haskell</a>, which allows you to try Haskell right in your browser and offers a rad interactive walkthrough.</p>
25+
<p>Another great Haskell resource is <a href="https://tryhaskell.org" rel="nofollow">Try Haskell</a>, which allows you to try Haskell right in your browser and offers a rad interactive walkthrough.</p>
2626
<h2>How do I get in touch with you?</h2>
2727
<p>The best way would be to shoot me an email to bonus at learnyouahaskell dot com. I kinda suck at email though, so please, please don't be mad if I don't reply in a timely fashion!</p>
2828
<h2>Your book is cool but I want some exercises too!</h2>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2389,7 +2389,7 @@ <h3>foldM</h3>
23892389

23902390
<p>
23912391
The monadic counterpart to <span class="fixed">foldl</span> is <span
2392-
class="fixed">foldM</span>. If you remember your folds from the <a href="http://learnyouahaskell.com/folds">folds section</a>, you know that <span class="fixed">foldl</span> takes a binary
2392+
class="fixed">foldM</span>. If you remember your folds from the <a href="../higher-order-functions.html#folds">folds section</a>, you know that <span class="fixed">foldl</span> takes a binary
23932393
function, a starting accumulator and a list to fold up and then folds it from the left
23942394
into a single value by using the binary function. <span class="fixed">foldM</span> does the same
23952395
thing, except it takes a binary function that produces a monadic value and folds

docs/functionally-solving-problems.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ <h1>Functionally Solving Problems</h1>
3535
<p>In this chapter, we'll take a look at a few interesting problems and how to think functionally to solve them as elegantly as possible. We probably won't be introducing any new concepts, we'll just be flexing our newly acquired Haskell muscles and practicing our coding skills. Each section will present a different problem. First we'll describe the problem, then we'll try and find out what the best (or least worst) way of solving it is.</p>
3636
<a name="reverse-polish-notation-calculator"></a><h2>Reverse Polish notation calculator</h2>
3737
<p>Usually when we write mathematical expressions in school, we write them in an infix manner. For instance, we write <span class="fixed">10 - (4 + 3) * 2</span>. <span class="fixed">+</span>, <span class="fixed">*</span> and <span class="fixed">-</span> are infix operators, just like the infix functions we met in Haskell (<span class="fixed">+</span>, <span class="fixed">`elem`</span>, etc.). This makes it handy because we, as humans, can parse it easily in our minds by looking at such an expression. The downside to it is that we have to use parentheses to denote precedence.</p>
38-
<p><a href="http://en.wikipedia.org/wiki/Reverse_Polish_notation">Reverse Polish notation</a> is another way of writing down mathematical expressions. Initially it looks a bit weird, but it's actually pretty easy to understand and use because there's no need for parentheses and it's very easy to punch into a calculator. While most modern calculators use infix notation, some people still swear by RPN calculators. This is what the previous infix expression looks like in RPN: <span class="fixed">10 4 3 + 2 * -</span>. How do we calculate what the result of that is? Well, think of a stack. You go over the expression from left to right. Every time a number is encountered, push it on to the stack. When we encounter an operator, take the two numbers that are on top of the stack (we also say that we <i>pop</i> them), use the operator and those two and then push the resulting number back onto the stack. When you reach the end of the expression, you should be left with a single number if the expression was well-formed and that number represents the result.</p>
38+
<p><a href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">Reverse Polish notation</a> is another way of writing down mathematical expressions. Initially it looks a bit weird, but it's actually pretty easy to understand and use because there's no need for parentheses and it's very easy to punch into a calculator. While most modern calculators use infix notation, some people still swear by RPN calculators. This is what the previous infix expression looks like in RPN: <span class="fixed">10 4 3 + 2 * -</span>. How do we calculate what the result of that is? Well, think of a stack. You go over the expression from left to right. Every time a number is encountered, push it on to the stack. When we encounter an operator, take the two numbers that are on top of the stack (we also say that we <i>pop</i> them), use the operator and those two and then push the resulting number back onto the stack. When you reach the end of the expression, you should be left with a single number if the expression was well-formed and that number represents the result.</p>
3939
<img src="http://s3.amazonaws.com/lyah/rpn.png" alt="this expression" class="center" width="626" height="224">
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>

docs/input-and-output.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ <h1>Input and Output</h1>
12691269
| otherwise = ioError e
12701270
</pre>
12711271
<p>Where <span class="fixed">notifyCops</span> and <span class="fixed">freeSomeSpace</span> are some I/O actions that you define. Be sure to re-throw exceptions if they don't match any of your criteria, otherwise you're causing your program to fail silently in some cases where it shouldn't.</p>
1272-
<p><span class="fixed">System.IO.Error</span> also exports functions that enable us to ask our exceptions for some attributes, like what the handle of the file that caused the error is, or what the filename is. These start with <span class="fixed">ioe</span> and you can see a <a href="http://www.haskell.org/ghc/docs/6.10.1/html/libraries/base/System-IO-Error.html#3">full list of them</a> in the documentation. Say we want to print the filename that caused our error. We can't print the <span class="fixed">fileName</span> that we got from <span class="fixed">getArgs</span>, because only the <span class="fixed">IOError</span> is passed to the handler and the handler doesn't know about anything else. A function depends only on the parameters it was called with. That's why we can use the <span class="label function">ioeGetFileName</span> function, which has a type of <span class="fixed">ioeGetFileName :: IOError -&gt; Maybe FilePath</span>. It takes an <span class="fixed">IOError</span> as a parameter and maybe returns a <span class="fixed">FilePath</span> (which is just a type synonym for <span class="fixed">String</span>, remember, so it's kind of the same thing). Basically, what it does is it extracts the file path from the <span class="fixed">IOError</span>, if it can. Let's modify our program to print out the file path that's responsible for the exception occurring.
1272+
<p><span class="fixed">System.IO.Error</span> also exports functions that enable us to ask our exceptions for some attributes, like what the handle of the file that caused the error is, or what the filename is. These start with <span class="fixed">ioe</span> and you can see a <a href="https://hackage.haskell.org/package/base/docs/System-IO-Error.html#g:3">full list of them</a> in the documentation. Say we want to print the filename that caused our error. We can't print the <span class="fixed">fileName</span> that we got from <span class="fixed">getArgs</span>, because only the <span class="fixed">IOError</span> is passed to the handler and the handler doesn't know about anything else. A function depends only on the parameters it was called with. That's why we can use the <span class="label function">ioeGetFileName</span> function, which has a type of <span class="fixed">ioeGetFileName :: IOError -&gt; Maybe FilePath</span>. It takes an <span class="fixed">IOError</span> as a parameter and maybe returns a <span class="fixed">FilePath</span> (which is just a type synonym for <span class="fixed">String</span>, remember, so it's kind of the same thing). Basically, what it does is it extracts the file path from the <span class="fixed">IOError</span>, if it can. Let's modify our program to print out the file path that's responsible for the exception occurring.
12731273
<pre name="code" class="haskell:hs">
12741274
import System.Environment
12751275
import System.IO

docs/introduction.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ <h2>About this tutorial</h2>
7272
</p>
7373
<a name="what-you-need"></a><h2>What you need to dive in</h2>
7474
<p>
75-
A text editor and a Haskell compiler. You probably already have your favorite text editor installed so we won't waste time on that. For the purposes of this tutorial we'll be using GHC, the most widely used Haskell compiler. The best way to get started is to download the <a href="http://hackage.haskell.org/platform/">Haskell Platform</a>, which is basically Haskell with batteries included.
75+
A text editor and a Haskell compiler. You probably already have your favorite text editor installed so we won't waste time on that. For the purposes of this tutorial we'll be using GHC, the most widely used Haskell compiler. The best way to get started is to download the <a href="https://www.haskell.org/platform/">Haskell Platform</a>, which is basically Haskell with batteries included.
7676
</p>
7777
<p>
7878
GHC can take a Haskell script (they usually have a .hs extension) and compile it but it also has an interactive mode which allows you to interactively interact with scripts. Interactively. You can call functions from scripts that you load and the results are displayed immediately. For learning it's a lot easier and faster than compiling every time you make a change and then running the program from the prompt. The interactive mode is invoked by typing in <span class="fixed">ghci</span> at your prompt. If you have defined some functions in a file called, say, <span class="fixed">myfunctions.hs</span>, you load up those functions by typing in <span class="fixed">:l myfunctions</span> and then you can play with them, provided <span class="fixed">myfunctions.hs</span> is in the same folder from which <span class="fixed">ghci</span> was invoked. If you change the .hs script, just run <span class="fixed">:l myfunctions</span> again or do <span class="fixed">:r</span>, which is equivalent because it reloads the current script. The usual workflow for me when playing around in stuff is defining some functions in a .hs file, loading it up and messing around with them and then changing the .hs file, loading it up again and so on. This is also what we'll be doing here.

docs/modules.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ <h1>Modules</h1>
7070
import qualified Data.Map as M
7171
</pre>
7272
<p>Now, to reference <span class="fixed">Data.Map</span>'s <span class="fixed">filter</span> function, we just use <span class="fixed">M.filter</span>.</p>
73-
<p>Use <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/">this handy reference</a> to see which modules are in the standard library. A great way to pick up new Haskell knowledge is to just click through the standard library reference and explore the modules and their functions. You can also view the Haskell source code for each module. Reading the source code of some modules is a really good way to learn Haskell and get a solid feel for it.</p>
74-
<p>To search for functions or to find out where they're located, use <a href="http://haskell.org/hoogle">Hoogle</a>. It's a really awesome Haskell search engine, you can search by name, module name or even type signature.</p>
73+
<p>Use <a href="https://downloads.haskell.org/~ghc/latest/docs/html/libraries/">this handy reference</a> to see which modules are in the standard library. A great way to pick up new Haskell knowledge is to just click through the standard library reference and explore the modules and their functions. You can also view the Haskell source code for each module. Reading the source code of some modules is a really good way to learn Haskell and get a solid feel for it.</p>
74+
<p>To search for functions or to find out where they're located, use <a href="https://hoogle.haskell.org/">Hoogle</a>. It's a really awesome Haskell search engine, you can search by name, module name or even type signature.</p>
7575
<a name="data-list"></a><h2>Data.List</h2>
7676
<p>The <span class="fixed">Data.List</span> module is all about lists, obviously. It provides some very useful functions for dealing with them. We've already met some of its functions (like <span class="fixed">map</span> and <span class="fixed">filter</span>) because the <span class="fixed">Prelude</span> module exports some functions from <span class="fixed">Data.List</span> for convenience. You don't have to import <span class="fixed">Data.List</span> via a qualified import because it doesn't clash with any <span class="fixed">Prelude</span> names except for those that <span class="fixed">Prelude</span> already steals from <span class="fixed">Data.List</span>. Let's take a look at some of the functions that we haven't met before.</p>
7777
<p><span class="label function">intersperse</span> takes an element and a list and then puts that element in between each pair of elements in the list. Here's a demonstration:</p>
@@ -707,7 +707,7 @@ <h1>Modules</h1>
707707
ghci&gt; Map.insertWith (+) 3 100 $ Map.fromList [(3,4),(5,103),(6,339)]
708708
fromList [(3,104),(5,103),(6,339)]
709709
</pre>
710-
<p>These were just a few functions from <span class="fixed">Data.Map</span>. You can see a complete list of functions in the <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.html#v%3Aassocs">documentation</a>.</p>
710+
<p>These were just a few functions from <span class="fixed">Data.Map</span>. You can see a complete list of functions in the <a href="https://hackage.haskell.org/package/containers/docs/Data-Map.html">documentation</a>.</p>
711711
<a name="data-set"></a><h2>Data.Set</h2>
712712
<img src="http://s3.amazonaws.com/lyah/legosets.png" alt="legosets" class="right" width="150" height="236">
713713
<p>The <span class="fixed">Data.Set</span> module offers us, well, sets. Like sets from mathematics. Sets are kind of like a cross between lists and maps. All the elements in a set are unique. And because they're internally implemented with trees (much like maps in <span class="fixed">Data.Map</span>), they're ordered. Checking for membership, inserting, deleting, etc. is much faster than doing the same thing with lists. The most common operation when dealing with sets are inserting into a set, checking for membership and converting a set to a list.</p>

0 commit comments

Comments
 (0)