forked from mightybyte/monad-challenges
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
127 lines (109 loc) · 8.03 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>The Monad Challenges</title>
<link rel="stylesheet" href="./stylesheets/styles.css">
<link rel="stylesheet" href="./stylesheets/github-light.css">
<script src="javascripts/scale.fix.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<header>
<h1 class="header"><a href="./">The Monad Challenges</a></h1>
<p class="header">A set of challenges for jump starting your understanding of monads.</p>
<h1 class="header">Outline</h1>
<p><a href="./pages/set1.html">Set 1: Random Numbers</a></p>
<p><a href="./pages/set2.html">Set 2: Failing Computations</a></p>
<p><a href="./pages/set3.html">Set 3: Combinations</a></p>
<p><a href="./pages/set4.html">Set 4: Common Abstraction</a></p>
<p><a href="./pages/set5.html">Set 5: Do Notation</a></p>
<ul>
<li class="download"><a class="buttons" href="https://github.com/mightybyte/monad-challenges/zipball/master">Download ZIP</a></li>
<li class="download"><a class="buttons" href="https://github.com/mightybyte/monad-challenges/tarball/master">Download TAR</a></li>
<li><a class="buttons github" href="https://github.com/mightybyte/monad-challenges">View On GitHub</a></li>
</ul>
<p class="author header">This project is maintained by <a class="header name" href="https://github.com/mightybyte">mightybyte</a></p>
<p class="license">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.
</p>
</header>
<section>
<h1>The Monad Challenges</h1>
<div class="notice">
<h3 id="work-in-progress">Work In Progress</h3>
<p>There are still some rough edges here, and also a fair amount of content to be added. But if we waited until everything was polished before publishing, it would probably never happen. So feel free to make comments, suggestions, or contribute new content. As always, pull requests are the most desirable.</p>
<p>Bottom line: <strong>we need more contributors</strong>. If you would like to help, see the <a href="https://github.com/mightybyte/monad-challenges/blob/gh-pages/README.md">contribution guide</a> for more information.</p>
</div>
<h2 id="welcome">Welcome</h2>
<p>The guys who wrote the <a href="http://cryptopals.com/">matasano crypto challenges</a> realized that you cannot get a working knowledge of crypto without investing blood, sweat, and tears into playing with and attempting to break crypto. They even say, “But more people ‘know how’ to break it than can actually break it.” Their crypto challenges provide a structured way for people to make the requisite blood, sweat, and tears investment to get to a place of understanding.</p>
<p>We believe the same is true when learning monads. Monads cannot be taught. They must be <em>discovered</em>. The problem with monad tutorials is that they are predicated on someone teaching/explaining monads. But you must explore them yourself. You will never really understand monads until you do this. The problem is that beginners do not usually know how to explore. We put together this set of challenges to show you how to do that.</p>
<p><em>Please do NOT publish the answers to these challenges.</em> Reading answers that you did not create yourself defeats the whole purpose.</p>
<h3 id="do-i-need-to-know-category-theory">Do I need to know category theory?</h3>
<p>No.</p>
<h3 id="do-i-need-to-know-haskell">Do I need to know Haskell?</h3>
<p>Yes, we assume that you have some beginner “pre-monad” level knowledge of the following Haskell concepts:</p>
<ul>
<li>Basic syntax</li>
<li>Type signatures</li>
<li>Higher order functions</li>
<li>Type synonyms</li>
<li>newtypes</li>
<li>Polymorphism</li>
<li>Type classes</li>
</ul>
<p>We are not trying to teach you Haskell here. We are trying to guide you down the path to a fully internalized working knowledge of monads. If you need to learn Haskell, go work through some beginning Haskell materials and come back when you think you need to learn monads.</p>
<h3 id="organizing-your-code">Organizing Your Code</h3>
<p>It will probably help if you organize your code into one file per set of challenges. Some of the problem sets build on previous ones, so it will be convenient to be able to easily import your code for a whole set or find it for reference.</p>
<h3 id="who-did-this">Who did this?</h3>
<ul>
<li>Doug Beardsley (with feedback and suggestions from Brent Yorgey)</li>
</ul>
<h3 id="code-template">Code Template</h3>
<p>For all of these problem sets you should use the following language pragmas and imports:</p>
<pre><code>{-# LANGUAGE MonadComprehensions #-}
{-# LANGUAGE RebindableSyntax #-}
module Set1 where
import MCPrelude</code></pre>
<p>MCPrelude should be the only module you import. Do not import any other modules. We are giving you a special prelude because we want you to solve these challenges without the use of monad libraries that have already done the work for you. Also, don’t look at the code in Control.Monad, the transformers package, or the mtl package. You’re doing this to learn. To do that you need to struggle with the concepts. Don’t cheat yourself out of the benefit you can get by working through things yourself.</p>
<h3 id="getting-started">Getting Started</h3>
<p>First clone the monad-challenges github repository and build the associated library.</p>
<pre><code>git clone https://github.com/mightybyte/monad-challenges.git
cd monad-challenges
cabal install</code></pre>
<p>This makes the MCPrelude module available on your system. Now head on over to <a href="pages/set1.html">Set 1</a> and start coding!</p>
<p>Once you’ve written some code, the easiest way to test it is to use Haskell’s REPL, <code>ghci</code>.</p>
<pre><code>ghci Set1.hs</code></pre>
<p>You can inspect symbols you’ve written just by typing them in <code>ghci</code>.</p>
<pre><code>$ ghci Set1.hs
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Set1 ( Set1.hs, interpreted )
Ok, modules loaded: Set1.
*Set1> fiveRands
[33614,564950498,1097816499,1969887316,140734213]
*Set1></code></pre>
<p>You can also type <code>:r</code> to reload Set1.hs after you make code changes. (Note that the above numbers are not the correct answer for fiveRands.)</p>
<h3 id="hex-decoding">Hex Decoding</h3>
<p>Some challenges include hex encoded hints if you get stuck. You can put “hex decoder” into your favorite search engine to find numerous web pages that will do the decoding for you. Or you can use this bit of Haskell:</p>
<pre><code>import Numeric (readHex)
import Data.List.Split (chunksOf)
hexDecode :: String -> String
hexDecode = map (toEnum . fst . head . readHex) . (chunksOf 2)</code></pre>
</section>
</div>
<!--[if !IE]><script>fixScale(document);</script><![endif]-->
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script><script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-72594732-1");
pageTracker._trackPageview();
} catch(err) {}
</script>
</body></html>