Skip to content

Commit 75b65e4

Browse files
committed
First article
1 parent 396e34f commit 75b65e4

File tree

9 files changed

+561
-3
lines changed

9 files changed

+561
-3
lines changed
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
5+
<meta charset="utf-8"/>
6+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
7+
8+
<title>PureScript – Articles</title>
9+
10+
<link rel="stylesheet" href="../../css/style.css"/>
11+
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:400,300,700"/>
12+
13+
</head>
14+
15+
<body class="download">
16+
17+
<header>
18+
<div class="wrap">
19+
<h1><a href="../">PureScript</a></h1>
20+
<nav>
21+
<h2>Menu</h2>
22+
<ul>
23+
<li><a href="../../">Home</a></li>
24+
<li><a href="../../download/">Download</a></li>
25+
<li><a href="../../learn/">Learn</a></li>
26+
<li><a href="../../projects/">Projects</a></li>
27+
<li><a href="../../articles/" class="active">Articles</a></li>
28+
</ul>
29+
</nav>
30+
</div>
31+
</header>
32+
33+
<main>
34+
35+
<section>
36+
37+
<h2>Getting Started with PureScript 0.7</h2>
38+
39+
<p>Welcome to the PureScript community blog! In this first post, I'm going to walk through the basics of getting set up to use the PureScript compiler <code>psc</code>, and its interactive mode <code>psci</code>.</p>
40+
<p>I'll start with the installation of the compiler, go through the basic commands of <code>psc</code> and <code>psci</code>, working towards a solution of problem 1 from <a href="http://projecteuler.net/problem=1">Project Euler</a>.</p>
41+
<h3 id="installing-the-compiler">Installing the Compiler</h3>
42+
<p>PureScript can be installed from <a href="http://hackage.haskell.org/package/purescript">Hackage</a> or by downloading the latest <a href="https://github.com/purescript/purescript/releases">binary bundle</a> for your OS.</p>
43+
<p>Make sure the <code>psc</code> executable is on your path.</p>
44+
<h3 id="setting-up-the-development-environment">Setting up the Development Environment</h3>
45+
<p>PureScript's core libraries are configured to use the Pulp build tool, and packages are available in the Bower registry.</p>
46+
<p>If you don't have Pulp installed, install it now:</p>
47+
<pre><code>npm install -g pulp</code></pre>
48+
<p>Create a new project in an empty directory using <code>pulp init</code>:</p>
49+
<pre><code>pulp init</code></pre>
50+
<p>Your directory should now contain the following files:</p>
51+
<ul>
52+
<li><code>bower.json</code> - contains library dependency information</li>
53+
<li><code>bower_components/</code> - a directory for installed dependencies</li>
54+
<li><code>src/Main.purs</code> - Entry point module for your project</li>
55+
<li><code>test/Main.purs</code> - An empty test suite</li>
56+
</ul>
57+
<p>At this point, you should be able to build the project and run the tests:</p>
58+
<pre><code>pulp build
59+
pulp test</code></pre>
60+
<p>You should see output similar to the following:</p>
61+
<pre><code>* Building project in /Users/paf31/Documents/Code/purescript/pulp-test
62+
* Build successful. Running tests...
63+
You should add some tests.
64+
* Tests OK.</code></pre>
65+
<p>If everything was built successfully, and the tests ran without problems, then the last line should state &quot;Tests OK&quot;.</p>
66+
<h3 id="installing-dependencies">Installing Dependencies</h3>
67+
<p>Dependencies can be installed using Bower, if you have it installed globally:</p>
68+
<pre><code>bower i purescript-lists --save</code></pre>
69+
<p>If you want to use Pulp, you can run <code>pulp dep</code>:</p>
70+
<pre><code>pulp dep i purescript-lists --save</code></pre>
71+
<h3 id="working-in-psci">Working in PSCI</h3>
72+
<p>PSCi is the interactive mode of PureScript. It is useful for working with pure computations, and for testing ideas.</p>
73+
<p>Open PSCi by typing <code>pulp psci</code> at the command line. Pulp will create a file in your directory called <code>.psci</code>, which contains instructions to PSCi to load your modules and dependencies. If you invoke the PSCi executable directly, you would need to load these files by hand.</p>
74+
<pre><code> ____ ____ _ _
75+
| _ \ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_
76+
| |_) | | | | &#39;__/ _ \___ \ / __| &#39;__| | &#39;_ \| __|
77+
| __/| |_| | | | __/___) | (__| | | | |_) | |_
78+
|_| \__,_|_| \___|____/ \___|_| |_| .__/ \__|
79+
|_|
80+
81+
:? shows help
82+
&gt;</code></pre>
83+
<p>As the introduction indicates, you can type <code>:?</code> to see a list of commands:</p>
84+
<pre><code>The following commands are available:
85+
86+
:? Show this help menu
87+
:quit Quit PSCi
88+
:reset Discard all imported modules and declared bindings
89+
:browse &lt;module&gt; See all functions in &lt;module&gt;
90+
:load &lt;file&gt; Load &lt;file&gt; for importing
91+
:foreign &lt;file&gt; Load foreign module &lt;file&gt;
92+
:type &lt;expr&gt; Show the type of &lt;expr&gt;
93+
:kind &lt;type&gt; Show the kind of &lt;type&gt;
94+
:show import Show all imported modules
95+
:show loaded Show all loaded modules
96+
97+
Further information is available on the PureScript wiki:
98+
--&gt; https://github.com/purescript/purescript/wiki/psci</code></pre>
99+
<p>We will use a selection of these commands during this tutorial.</p>
100+
<p>Start by pressing the Tab key to use the autocompletion feature. You will see a collection of names of functions from the Prelude which are available to use.</p>
101+
<p>To see the type of one of these values, use the <code>:type</code> command, followed by a space, followed by the name of the value:</p>
102+
<pre><code>&gt; :type Prelude.map
103+
forall a b f. (Prelude.Functor f) =&gt; (a -&gt; b) -&gt; f a -&gt; f b
104+
&gt; :type Data.List.zip
105+
forall a b. Data.List.List a -&gt; Data.List.List b -&gt; Data.List.List (Data.Tuple.Tuple a b)</code></pre>
106+
<p>We will be using some of the functions from the <code>Prelude</code> and <code>Data.List</code> modules, so import those by using the <code>import</code> keyword:</p>
107+
<pre><code>import Prelude
108+
import Data.List</code></pre>
109+
<p>Note that using <code>Tab</code> to autocomplete names can be a useful time-saving device in <code>psci</code>.</p>
110+
<h3 id="solving-project-euler-1">Solving Project Euler #1</h3>
111+
<p>The following problem is taken from <a href="http://projecteuler.net/problem=1">Project Euler</a>:</p>
112+
<blockquote>
113+
<p>If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.</p>
114+
<p>Find the sum of all the multiples of 3 or 5 below 1000.</p>
115+
</blockquote>
116+
<p>We can solve this problem neatly using functions and function composition, directly in <code>psci</code>.</p>
117+
<p>Let's start by listing all of the natural numbers below 1000 as a list. We can do this using the <code>range</code> function from <code>Data.List</code>:</p>
118+
<pre><code>&gt; range 0 999</code></pre>
119+
<p>You should see a list with 1000 elements printed to the command line.</p>
120+
<p>This value can be given a name, using a <code>let</code> binding:</p>
121+
<pre><code>&gt; let ns = range 0 999</code></pre>
122+
<p>Now let's filter out all of those elements which do not meet the criterion. We can use the <code>filter</code> function from <code>Data.List</code>, by providing a predicate function as its first argument:</p>
123+
<pre><code>&gt; let multiples = filter (\n -&gt; mod n 3 == 0 || mod n 5 == 0) ns</code></pre>
124+
<p>You can see the result by evaluating <code>multiples</code> if you like, or even check its type:</p>
125+
<pre><code>&gt; multiples
126+
Cons 0 (Cons 3 (Cons 5 (Cons 6 (Cons ...
127+
&gt; :type multiples
128+
List Int</code></pre>
129+
<p>Now we need to find the sum of the <code>multiples</code> array, to complete the solution. We can use the <code>sum</code> function from the <code>Data.Foldable</code> module.</p>
130+
<pre><code>&gt; import Data.Foldable
131+
&gt; sum multiples
132+
233168</code></pre>
133+
<p>When you have finished using PSCi, type <code>:quit</code> to quit:</p>
134+
<pre><code>&gt; :quit
135+
See ya!</code></pre>
136+
<h3 id="compiling-a-solution">Compiling a Solution</h3>
137+
<p>Now that we've seen how to use <code>psci</code> to reach the answer, let's move our solution into a source file, and compile it using <code>psc</code>.</p>
138+
<p>Create a new text file <code>src/Euler.purs</code> and copy the following code:</p>
139+
<pre class="purescript"><code>module Euler1 where
140+
141+
import Prelude
142+
143+
import Data.List (range, filter)
144+
import Data.Foldable (sum)
145+
146+
ns = range 0 999
147+
148+
multiples = filter (\n -&gt; mod n 3 == 0 || mod n 5 == 0) ns
149+
150+
answer = sum multiples</code></pre>
151+
<p>It is possible to load this file directly into PSCi and to continue working:</p>
152+
<pre><code>pulp psci
153+
&gt; Euler1.answer
154+
233168
155+
&gt; :quit
156+
See ya!</code></pre>
157+
<p>Alternatively, we can use Pulp to compile our new module to Javascript:</p>
158+
<pre><code>pulp build</code></pre>
159+
<p>This will compile each module present in <code>src/</code> into a separate file in the <code>output/</code> directory.</p>
160+
<h3 id="writing-a-test-suite">Writing a Test Suite</h3>
161+
<p>To test our code, we'll use the <code>purescript-assert</code> library:</p>
162+
<pre><code>bower i purescript-assert --save</code></pre>
163+
<p>Modify the <code>test/Main.purs</code> file, and add the following code:</p>
164+
<pre class="purescript"><code>module Test.Main where
165+
166+
import Prelude
167+
import Euler1 (answer)
168+
import Test.Assert (assert)
169+
170+
main = do
171+
assert (answer == 233168)</code></pre>
172+
<p>Our &quot;test suite&quot; is just a single assertion that the <code>answer</code> value equals the correct integer. In a real test suite, we might use the <code>Eff</code> monad to compose multiple tests in our <code>main</code> function.</p>
173+
<p>Run the tests using <code>pulp test</code>, and you should hopefully see &quot;Tests OK&quot; in the last line.</p>
174+
<h3 id="creating-executables">Creating Executables</h3>
175+
<p>We can modify the <code>main</code> function in the <code>src/Main.purs</code> module to print our result to the console:</p>
176+
<pre class="purescript"><code>module Main where
177+
178+
import Prelude
179+
import Euler1
180+
import Control.Monad.Eff.Console
181+
182+
main = do
183+
log (&quot;The answer is &quot; ++ show answer)</code></pre>
184+
<p>The <code>pulp run</code> command can be used to compile and run the <code>Main</code> module:</p>
185+
<pre><code>&gt; pulp run
186+
* Building project in /Users/paf31/Documents/Code/purescript/pulp-test
187+
* Build successful.
188+
The answer is 233168</code></pre>
189+
<h3 id="conclusion">Conclusion</h3>
190+
<p>That's all for this post. We've seen how to use enough of the basics of <code>psc</code> and PSCi to compile, execute and test simple PureScript programs. If you would like more information, the <a href="http://docs.purescript.org">PureScript documentation</a> lists all of the options for both <code>psc</code> and <code>psci</code>.</p>
191+
<p>Until next time...</p>
192+
193+
</section>
194+
195+
</main>
196+
197+
<footer>
198+
<nav>
199+
<ul>
200+
<li><a href="../../">Home</a></li>
201+
<li><a href="../../download/" class="active">Download</a></li>
202+
<li><a href="../../learn/">Learn</a></li>
203+
<li><a href="../../projects/">Projects</a></li>
204+
<li><a href="../../articles/" class="active">Articles</a></li>
205+
</ul>
206+
<ul class="external">
207+
<li class="github"><a href="https://github.com/purescript/purescript" title="GitHub">GitHub</a></li>
208+
<li class="twitter"><a href="https://twitter.com/purescript" title="Twitter">Twitter</a></li>
209+
</ul>
210+
</nav>
211+
</footer>
212+
213+
<script>
214+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
215+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
216+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
217+
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
218+
219+
ga('create', 'UA-56579671-1', 'auto');
220+
ga('send', 'pageview');
221+
222+
</script>
223+
224+
</body>
225+
</html>

0 commit comments

Comments
 (0)