Skip to content

Commit 40282fa

Browse files
authored
Merge branch 'learnyouahaskell:main' into main
2 parents f1f6f61 + 304692b commit 40282fa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+32648
-7
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Well, I began learning Haskell in 2021 at my undergrad studies and quickly came
1212

1313
However, I quickly realised some parts are slowly becoming outdated as Haskell continues to evolve. That is why, with the author's blessing, I decided to create this open-source fork to enable the Haskell community to participate in preserving and maintaining this awesome resource for the future times.
1414

15-
Anyone is invited to **contribute** be either opening a pull request (preferred) or opening a content edit request (in the pipeline, open soon!) for proposed changes.
15+
Anyone is invited to **contribute** by either opening a pull request (preferred) or opening a content edit request (in the pipeline, open soon!) for proposed changes.
1616

1717
The whole thing is completely free to read online, but the original is also available in print and we encourage you to buy a copy!
1818

docs/making-our-own-types-and-typeclasses.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ <h1>Making Our Own Types and Typeclasses</h1>
156156
ghci&gt; guy
157157
Person "Buddy" "Finklestein" 43 184.2 "526-2928" "Chocolate"
158158
</pre>
159-
<p>That's kind of cool, although slightly unreadable. What if we want to create a function to get seperate info from a person? A function that gets some person's first name, a function that gets some person's last name, etc. Well, we'd have to define them kind of like this.</p>
159+
<p>That's kind of cool, although slightly unreadable. What if we want to create a function to get separate info from a person? A function that gets some person's first name, a function that gets some person's last name, etc. Well, we'd have to define them kind of like this.</p>
160160
<pre name="code" class="haskell:hs">
161161
firstName :: Person -&gt; String
162162
firstName (Person firstname _ _ _ _ _) = firstname

docs/modules.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ <h1>Modules</h1>
8181
ghci&gt; intersperse 0 [1,2,3,4,5,6]
8282
[1,0,2,0,3,0,4,0,5,0,6]
8383
</pre>
84-
<p><span class="label function">intercalate</span> takes a list of lists and a list. It then inserts that list in between all those lists and then flattens the result.</p>
84+
<p><span class="label function">intercalate</span> takes a list and a list of lists. It then inserts that list in between all those lists and then flattens the result.</p>
8585
<pre name="code" class="haskell:ghci">
8686
ghci&gt; intercalate " " ["hey","there","guys"]
8787
"hey there guys"
@@ -276,7 +276,7 @@ <h1>Modules</h1>
276276
find :: (a -&gt; Bool) -&gt; [a] -&gt; Maybe a
277277
</pre>
278278
<p>Notice the type of <span class="fixed">find</span>. Its result is <span class="fixed">Maybe a</span>. That's kind of like having the type of <span class="fixed">[a]</span>, only a value of the type <span class="fixed">Maybe</span> can contain either no elements or one element, whereas a list can contain no elements, one element or several elements.</p>
279-
<p>Remember when we were searching for the first time our stock went over $1000. We did <span class="fixed">head (dropWhile (\(val,y,m,d) -&gt; val &lt; 1000) stock)</span>. Remember that <span class="fixed">head</span> is not really safe. What would happen if our stock never went over $1000? Our application of <span class="fixed">dropWhile</span> would return an empty list and getting the head of an empty list would result in an error. However, if we rewrote that as <span class="fixed">find (\(val,y,m,d) -&gt; val &gt; 1000) stock</span>, we'd be much safer. If our stock never went over $1000 (so if no element satisfied the predicate), we'd get back a <span class="fixed">Nothing</span>. But there was a valid answer in that list, we'd get, say, <span class="fixed">Just (1001.4,2008,9,4)</span>.
279+
<p>Remember when we were searching for the first time our stock went over $1000. We did <span class="fixed">head (dropWhile (\(val,y,m,d) -&gt; val &lt; 1000) stock)</span>. Remember that <span class="fixed">head</span> is not really safe. What would happen if our stock never went over $1000? Our application of <span class="fixed">dropWhile</span> would return an empty list and getting the head of an empty list would result in an error. However, if we rewrote that as <span class="fixed">find (\(val,y,m,d) -&gt; val &gt; 1000) stock</span>, we'd be much safer. If our stock never went over $1000 (so if no element satisfied the predicate), we'd get back a <span class="fixed">Nothing</span>. But if there was a valid answer in that list, we'd get, say, <span class="fixed">Just (1001.4,2008,9,4)</span>.
280280
<p><span class="label function">elemIndex</span> is kind of like <span class="fixed">elem</span>, only it doesn't return a boolean value. It maybe returns the index of the element we're looking for. If that element isn't in our list, it returns a <span class="fixed">Nothing</span>. </p>
281281
<pre name="code" class="haskell:ghci">
282282
ghci&gt; :t elemIndex
@@ -308,7 +308,7 @@ <h1>Modules</h1>
308308
[(2,2,5,2),(3,2,5,2),(3,2,3,2)]
309309
</pre>
310310
<p>Just like with normal zipping, lists that are longer than the shortest list that's being zipped are cut down to size.</p>
311-
<p><span class="label function">lines</span> is a useful function when dealing with files or input from somewhere. It takes a string and returns every line of that string in a separate list.</p>
311+
<p><span class="label function">lines</span> is a useful function when dealing with files or input from somewhere. It takes a string and returns every line of that string as separate element of a list.</p>
312312
<pre name="code" class="haskell:ghci">
313313
ghci&gt; lines "first line\nsecond line\nthird line"
314314
["first line","second line","third line"]
@@ -423,7 +423,7 @@ <h1>Modules</h1>
423423
<p><span class="label function">isOctDigit</span> checks whether a character is an octal digit.</p>
424424
<p><span class="label function">isHexDigit</span> checks whether a character is a hex digit.</p>
425425
<p><span class="label function">isLetter</span> checks whether a character is a letter.</p>
426-
<p><span class="label function">isMark</span> checks for Unicode mark characters. Those are characters that combine with preceding letters to form latters with accents. Use this if you are French.</p>
426+
<p><span class="label function">isMark</span> checks for Unicode mark characters. Those are characters that combine with preceding letters to form letters with accents. Use this if you are French.</p>
427427
<p><span class="label function">isNumber</span> checks whether a character is numeric.</p>
428428
<p><span class="label function">isPunctuation</span> checks whether a character is punctuation.</p>
429429
<p><span class="label function">isSymbol</span> checks whether a character is a fancy mathematical or currency symbol.</p>
@@ -635,7 +635,7 @@ <h1>Modules</h1>
635635
fromList [(3,9),(5,9)]
636636
</pre>
637637
<p><span class="label function">lookup</span> works like the <span class="fixed">Data.List</span> <span class="fixed">lookup</span>, only it operates on maps. It returns <span class="fixed">Just something</span> if it finds something for the key and <span class="fixed">Nothing</span> if it doesn't.</p>
638-
<p><span class="label function">member</span> is a predicate takes a key and a map and reports whether the key is in the map or not.</p>
638+
<p><span class="label function">member</span> is a predicate that takes a key and a map and reports whether the key is in the map or not.</p>
639639
<pre name="code" class="haskell:ghci">
640640
ghci&gt; Map.member 3 $ Map.fromList [(3,6),(4,3),(6,9)]
641641
True

markdown/config/file-list.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
introduction
2+
starting-out
3+
types-and-typeclasses
4+
syntax-in-functions
5+
recursion
6+
higher-order-functions
7+
modules
8+
making-our-own-types-and-typeclasses
9+
input-and-output
10+
functionally-solving-problems
11+
functors-applicative-functors-and-monoids
12+
a-fistful-of-monads
13+
for-a-few-monads-more
14+
zippers

markdown/config/pandoc-defaults.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from: markdown-implicit_figures
2+
to: html
3+
highlight-style: null
4+
standalone: true

markdown/config/template.html

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
2+
"https://www.w3.org/TR/html4/strict.dtd">
3+
<html>
4+
<head>
5+
<title>$title$ - Learn You a Haskell for Great Good!</title>
6+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
7+
<base href="">
8+
<style type="text/css">
9+
@import url('reset.css');
10+
@import url('style.css');
11+
</style>
12+
<link rel="shortcut icon" href="assets/images/favicon.png" type="image/png">
13+
$if(prev_filename)$
14+
<link rel="prev" href="${prev_filename}.html">
15+
$endif$
16+
$if(next_filename)$
17+
<link rel="next" href="${next_filename}.html">
18+
$endif$
19+
<link type="text/css" rel="stylesheet" href="sh/Styles/SyntaxHighlighter.css">
20+
<link href="rss.php" rel="alternate" type="application/rss+xml" title="Learn You a Haskell for Great Good! feed">
21+
</head>
22+
<body class="introcontent">
23+
<div class="bgwrapper">
24+
<div id="content">
25+
$if(footdiv)$
26+
<div class="footdiv" style="margin-bottom:25px;">
27+
<ul>
28+
<li style="text-align:left">
29+
$if(prev_filename)$
30+
<a href="${prev_filename}.html" class="prevlink">$prev_title$</a>
31+
$endif$
32+
</li>
33+
<li style="text-align:center">
34+
<a href="chapters.html">Table of contents</a>
35+
</li>
36+
<li style="text-align:right">
37+
$if(next_filename)$
38+
<a href="${next_filename}.html" class="nxtlink">$next_title$</a>
39+
$endif$
40+
</li>
41+
</ul>
42+
</div>
43+
$endif$
44+
$body$
45+
$if(footdiv)$
46+
<div class="footdiv">
47+
<ul>
48+
<li style="text-align:left">
49+
$if(prev_filename)$
50+
<a href="$prev_filename$.html" class="prevlink">$prev_title$</a>
51+
$endif$
52+
</li>
53+
<li style="text-align:center">
54+
<a href="chapters.html">Table of contents</a>
55+
</li>
56+
<li style="text-align:right">
57+
$if(next_filename)$
58+
<a href="$next_filename$.html" class="nxtlink">$next_title$</a>
59+
$endif$
60+
</li>
61+
</ul>
62+
</div>
63+
$endif$
64+
$if(faq)$
65+
<div class="footdiv">
66+
<ul>
67+
<li style="text-align:center">
68+
<a href="index.html" rel="nofollow">Back</a>
69+
</li>
70+
</ul>
71+
</div>
72+
$endif$
73+
</div>
74+
<script type="text/javascript" src="sh/Scripts/shCore.js"></script>
75+
<script type="text/javascript" src="shBrushHaskell.js"></script>
76+
<script type="text/javascript" src="shBrushPlain.js"></script>
77+
<script type="text/javascript">
78+
dp.SyntaxHighlighter.ClipboardSwf = '/sh/Scripts/clipboard.swf';
79+
dp.SyntaxHighlighter.HighlightAll('code', false, false, false, 1, false);
80+
</script>
81+
</div>
82+
<script type="text/javascript">
83+
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
84+
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
85+
</script>
86+
<script type="text/javascript">
87+
var pageTracker = _gat._getTracker("UA-4461592-3");
88+
pageTracker._trackPageview();
89+
</script>
90+
</body>
91+
</html>

markdown/generate.sh

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/bash
2+
3+
mapfile -t filename <config/file-list.txt
4+
5+
chapterfile=generated_md/chapters.md
6+
titlesuffix=" - Learn You a Haskell for Great Good!"
7+
8+
cp source_md/chapters_head.md $chapterfile
9+
10+
for i in ${!filename[@]}
11+
do
12+
sourcemd=source_md/${filename[$i]}.md
13+
14+
title[$i]=$(sed -n '/^# /s/# //p;' $sourcemd | sed 's/{.*//' | sed 's/ *$//g')
15+
16+
chnum=$(($i + 1))
17+
if [[ $chnum -ge 10 ]];
18+
then
19+
sp=" "
20+
else
21+
sp=" "
22+
fi
23+
24+
sed -n '/^#\{1,2\} /p' $sourcemd \
25+
| sed "s/^# *\(.*[^ ]\) *{.*/$chnum.$sp[\1](${filename[$i]}.html)/" \
26+
| sed "s/^# *\(.*[^ ]\) */$chnum.$sp[\1](${filename[$i]}.html)/" \
27+
| sed "s/^## *\(.*[^ ]\) *{ *#\(.*\)}/ * [\1](${filename[$i]}.html\#\2)/" \
28+
>>$chapterfile
29+
done
30+
31+
for i in ${!filename[@]}
32+
do
33+
if (($i <= 0))
34+
then
35+
prev_title=
36+
prev_filename=
37+
else
38+
prev=$(($i - 1))
39+
prev_title="${title[$prev]}"
40+
prev_filename=${filename[$prev]}
41+
fi
42+
if (($i >= ${#filename[@]} - 1))
43+
then
44+
next_title=
45+
next_filename=
46+
else
47+
next=$(($i + 1))
48+
next_title="${title[$next]}"
49+
next_filename=${filename[$next]}
50+
fi
51+
52+
pandoc -d config/pandoc-defaults.yml --template=config/template.html \
53+
-V footdiv=true -V title="${title[$i]}" \
54+
--metadata title="${title[$i]}$titlesuffix" \
55+
-V prev_title="$prev_title" -V prev_filename=$prev_filename \
56+
-V next_title="$next_title" -V next_filename=$next_filename \
57+
-o generated_html/${filename[$i]}.html source_md/${filename[$i]}.md
58+
done
59+
60+
cat source_md/chapters_foot.md >>$chapterfile
61+
62+
pandoc -d config/pandoc-defaults.yml --template=config/template.html \
63+
-V title="Chapters" --metadata title="${title[$i]}$titlesuffix" \
64+
-o generated_html/chapters.html $chapterfile
65+
66+
pandoc -d config/pandoc-defaults.yml --template=config/template.html \
67+
-V faq=true -V title="FAQ" --metadata title="${title[$i]}$titlesuffix" \
68+
-o generated_html/faq.html source_md/faq.md

0 commit comments

Comments
 (0)