Skip to content

Commit a038085

Browse files
committed
Merge pull request #94 from purescript/stack-unpack
Update download page to use stack unpack
2 parents c92587b + a6fe11e commit a038085

File tree

7 files changed

+117
-95
lines changed

7 files changed

+117
-95
lines changed

_site/download/index.html

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,28 @@ <h2>Homebrew</h2>
6565

6666
<h2>Stack</h2>
6767

68-
<p><a href="https://www.haskell.org/ghc/">GHC</a> 7.10.1 or newer is required to compile from source. The easiest way is to use <a href="https://github.com/commercialhaskell/stack">Stack</a>:</p>
68+
<p><a href="https://www.haskell.org/ghc/">GHC</a> 7.10.1 or newer is required to compile from source. The easiest way is to use <a href="https://github.com/commercialhaskell/stack">Stack</a>.</p>
69+
70+
<p>Update the Hackage package index:</p>
6971
<pre>
70-
stack install purescript --resolver=nightly
71-
</pre>
72+
stack update</pre>
73+
74+
<p>Download the latest source distribution and place it into a new directory in the current directory:</p>
75+
<pre>
76+
stack unpack purescript</pre>
77+
78+
<p>Compile and install PureScript:</p>
79+
<pre>
80+
cd purescript-x.y.z # (replace x.y.z with whichever version you just downloaded)
81+
stack install</pre>
7282

7383
<p>This will copy the compiler and utilities into <code>~/.local/bin</code>.</p>
7484

7585
<p>If you don't have Stack installed, there are install instructions <a href="https://github.com/commercialhaskell/stack/blob/master/doc/install_and_upgrade.md">here</a>.</p>
7686

87+
<p>You can also install a specific version by specifying it in the <code>stack unpack</code> step. For example, to install 0.8.5, use:</p>
88+
<pre>
89+
stack unpack purescript-0.8.5</pre>
7790
</section>
7891

7992
<section>

_site/learn/eff/index.html

Lines changed: 35 additions & 33 deletions
Large diffs are not rendered by default.

_site/learn/ffi/index.html

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ <h4 id="calling-purescript-from-javascript">Calling PureScript from Javascript</
4646
<p>Let’s take the following simple module as an example:</p>
4747
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">module</span> <span class="dt">Test</span> <span class="kw">where</span>
4848

49+
<span class="kw">import </span><span class="dt">Prelude</span>
50+
4951
gcd<span class="ot"> ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span>
5052
gcd n m <span class="fu">|</span> n <span class="fu">==</span> <span class="dv">0</span> <span class="fu">=</span> m
5153
gcd n m <span class="fu">|</span> m <span class="fu">==</span> <span class="dv">0</span> <span class="fu">=</span> n
@@ -69,28 +71,22 @@ <h4 id="understanding-name-generation">Understanding Name Generation</h4>
6971
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell">example' <span class="fu">=</span> <span class="dv">100</span></code></pre></div>
7072
<p>generates the following Javascript:</p>
7173
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> example$prime <span class="op">=</span> <span class="dv">100</span><span class="op">;</span></code></pre></div>
72-
<p>This scheme also applies to names of infix operators:</p>
73-
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell">(<span class="fu">%</span>) a b <span class="fu">=</span> <span class="fu">...</span></code></pre></div>
74-
<p>generates</p>
75-
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> $percent <span class="op">=</span> <span class="kw">function</span>(a) <span class="op">{</span> ... <span class="op">}</span></code></pre></div>
7674
<h4 id="calling-javascript-from-purescript">Calling Javascript from PureScript</h4>
7775
<p>Javascript values and functions can be used from PureScript by using the FFI. The problem becomes how to choose suitable types for values originating in Javascript.</p>
7876
<p>The general rule regarding types is that you can enforce as little or as much type safety as you like when using the FFI, but you should be careful to avoid common pitfalls when dealing with Javascript values, like the possibility of null or undefined values being returned from a Javascript function. Functions defined in the Prelude and core libraries tend to err on the side of type safety where possible.</p>
7977
<h4 id="foreign-modules">Foreign Modules</h4>
8078
<p>In PureScript, JavaScript code is wrapped using a <em>foreign module</em>. A foreign module is just a CommonJS module which is associated with a PureScript module. Foreign modules are required to adhere to certain conventions:</p>
8179
<ul>
82-
<li>The module must contain a comment of the form <code>// module ModuleName</code>, which associates the foreign module with its companion PureScript module.</li>
80+
<li>The name of the foreign module must be the same as its companion PureScript module, with its extension changed to <code>.js</code>. This associates the foreign module with the PureScript module.</li>
8381
<li>All exports must be of the form <code>exports.name = value;</code>, specified at the top level.</li>
8482
</ul>
8583
<p>Here is an example, where we export a function which computes interest amounts from a foreign module:</p>
8684
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="st">&quot;use strict&quot;</span><span class="op">;</span>
8785

88-
<span class="co">// module Interest</span>
89-
9086
<span class="va">exports</span>.<span class="at">calculateInterest</span> <span class="op">=</span> <span class="kw">function</span>(amount) <span class="op">{</span>
9187
<span class="cf">return</span> amount <span class="op">*</span> <span class="fl">0.1</span><span class="op">;</span>
9288
<span class="op">};</span></code></pre></div>
93-
<p>This file should be saved as <code>src/Interest.js</code>. The corresponding PureScript module <code>Interest</code> will be saved in <code>src/Interest.purs</code> (these filenames are merely conventions, but are used by certain tools, such as the Pulp build tool), and will look like this:</p>
89+
<p>This file should be saved as <code>src/Interest.js</code>. The corresponding PureScript module <code>Interest</code> will be saved in <code>src/Interest.purs</code>, and will look like this:</p>
9490
<pre class="purescript"><code>module Interest where
9591

9692
foreign import calculateInterest :: Number -&gt; Number</code></pre>
@@ -100,23 +96,21 @@ <h4 id="functions-of-multiple-arguments">Functions of Multiple Arguments</h4>
10096
<p>Suppose we wanted to modify our <code>calculateInterest</code> function to take a second argument:</p>
10197
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="st">&quot;use strict&quot;</span><span class="op">;</span>
10298

103-
<span class="co">// module Interest</span>
104-
10599
<span class="va">exports</span>.<span class="at">calculateInterest</span> <span class="op">=</span> <span class="kw">function</span>(amount<span class="op">,</span> months) <span class="op">{</span>
106100
<span class="cf">return</span> amount <span class="op">*</span> <span class="va">Math</span>.<span class="at">exp</span>(<span class="fl">0.1</span><span class="op">,</span> months)<span class="op">;</span>
107101
<span class="op">};</span></code></pre></div>
108102
<p>A correct <code>foreign import</code> declaration now should use a foreign type whose runtime representation correctly handles functions of multiple arguments. The <code>purescript-functions</code> package provides a collection of such types for function arities from 0 to 10:</p>
109103
<pre class="purescript"><code>module Interest where
110104

105+
import Data.Function (Fn2)
106+
111107
foreign import calculateInterest :: Fn2 Number Number Number</code></pre>
112108
<p>Here, the <code>Fn2</code> type constructor is used to wrap Javascript functions of two arguments. We can write a curried wrapper function in PureScript which will allow partial application:</p>
113109
<pre class="purescript"><code>calculateInterestCurried :: Number -&gt; Number -&gt; Number
114110
calculateInterestCurried = runFn2 calculateInterest</code></pre>
115111
<p>An alternative is to use curried functions in the native module, using multiple nested functions, each with a single argument, as the runtime representation of the function type constructor <code>(-&gt;)</code> dictates:</p>
116112
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="st">&quot;use strict&quot;</span><span class="op">;</span>
117113

118-
<span class="co">// module Interest</span>
119-
120114
<span class="va">exports</span>.<span class="at">calculateInterest</span> <span class="op">=</span> <span class="kw">function</span>(amount) <span class="op">{</span>
121115
<span class="cf">return</span> <span class="kw">function</span>(months) <span class="op">{</span>
122116
<span class="cf">return</span> amount <span class="op">*</span> <span class="va">Math</span>.<span class="at">exp</span>(<span class="fl">0.1</span><span class="op">,</span> months)<span class="op">;</span>
@@ -129,9 +123,10 @@ <h4 id="handling-constrained-types">Handling Constrained Types</h4>
129123
<p>For example, let’s write a simple PureScript function with a constrained type, and look at the generated Javascript.</p>
130124
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">module</span> <span class="dt">Test</span> <span class="kw">where</span>
131125

132-
<span class="kw">import </span><span class="dt">Data.Tuple</span>
126+
<span class="kw">import </span><span class="dt">Prelude</span>
127+
<span class="kw">import </span><span class="dt">Data.Tuple</span> (<span class="dt">Tuple</span>(..))
133128

134-
<span class="ot">inOrder ::</span> forall a<span class="fu">.</span> (<span class="dt">Ord</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Tuple</span> a a
129+
<span class="ot">inOrder ::</span> forall a<span class="fu">.</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Tuple</span> a a
135130
inOrder a1 a2 <span class="fu">|</span> a1 <span class="fu">&lt;</span> a2 <span class="fu">=</span> <span class="dt">Tuple</span> a1 a2
136131
inOrder a1 a2 <span class="fu">=</span> <span class="dt">Tuple</span> a2 a1</code></pre></div>
137132
<p>The generated Javascript looks like this:</p>

_site/learn/generic/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ <h4 id="generics-overview">Generics Overview</h4>
4343
<p>PureScript’s generics are supported by the <code>purescript-generics</code> library, and in particular, the <code>Data.Generic.Generic</code> type class:</p>
4444
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">class</span> <span class="dt">Generic</span> a <span class="kw">where</span>
4545
<span class="ot"> toSignature ::</span> <span class="dt">Proxy</span> a <span class="ot">-&gt;</span> <span class="dt">GenericSignature</span>
46-
<span class="ot"> toSpine ::</span> a <span class="ot">-&gt;</span> <span class="dt">GenericSpine</span>
47-
<span class="ot"> fromSpine ::</span> <span class="dt">GenericSpine</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</code></pre></div>
46+
<span class="ot"> toSpine ::</span> a <span class="ot">-&gt;</span> <span class="dt">GenericSpine</span>
47+
<span class="ot"> fromSpine ::</span> <span class="dt">GenericSpine</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</code></pre></div>
4848
<p><code>Generic</code> defines three functions:</p>
4949
<ul>
5050
<li><code>toSignature</code> creates a generic <em>signature</em> for a type. We can think of this as a representation of a type at runtime.</li>
@@ -85,7 +85,7 @@ <h4 id="handling-foreign-data">Handling Foreign Data</h4>
8585
return <span class="fu">$</span> <span class="dt">Person</span> { name, location }</code></pre></div>
8686
<p>This is not too bad, but real-world records often contain many more fields. Let’s see how to verify the same data using <code>Generic</code>.</p>
8787
<p>The <code>purescript-foreign-generic</code> library defines a function <code>readGeneric</code>, with the following type:</p>
88-
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">readGeneric ::</span> forall a<span class="fu">.</span> (<span class="dt">Generic</span> a) <span class="ot">=&gt;</span> <span class="dt">Options</span> <span class="ot">-&gt;</span> <span class="dt">Foreign</span> <span class="ot">-&gt;</span> <span class="dt">F</span> a</code></pre></div>
88+
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">readGeneric ::</span> forall a<span class="fu">.</span> <span class="dt">Generic</span> a <span class="ot">=&gt;</span> <span class="dt">Options</span> <span class="ot">-&gt;</span> <span class="dt">Foreign</span> <span class="ot">-&gt;</span> <span class="dt">F</span> a</code></pre></div>
8989
<p>The <code>Options</code> type here is based on the options record from Haskell’s <code>aeson</code> library. For our purposes, the default options will work, but we need to turn on the <code>unwrapNewtypes</code> option, so that our <code>newtype</code> constructor gets ignored during serialization:</p>
9090
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">myOptions ::</span> <span class="dt">Options</span>
9191
myOptions <span class="fu">=</span> defaultOptions { unwrapNewtypes <span class="fu">=</span> true }</code></pre></div>

_site/learn/getting-started/index.html

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ <h2>Menu</h2>
3636
<main>
3737
<section class="article">
3838
<h2>Getting Started with PureScript</h2>
39-
<div class="meta">By Phil Freeman, published on December 13, 2015</div>
39+
<div class="meta">By Phil Freeman, published on May 24, 2016</div>
4040

4141
<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>
4242
<p>I’ll start with the installation of the compiler and Pulp build tool, and then go through the basic usage of <code>psci</code>, working towards a solution of problem 1 from <a href="http://projecteuler.net/problem=1">Project Euler</a>.</p>
@@ -73,14 +73,8 @@ <h4 id="installing-dependencies">Installing Dependencies</h4>
7373
<h4 id="working-in-psci">Working in PSCI</h4>
7474
<p>PSCi is the interactive mode of PureScript. It is useful for working with pure computations, and for testing ideas.</p>
7575
<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>
76-
<pre><code> ____ ____ _ _
77-
| _ \ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_
78-
| |_) | | | | '__/ _ \___ \ / __| '__| | '_ \| __|
79-
| __/| |_| | | | __/___) | (__| | | | |_) | |_
80-
|_| \__,_|_| \___|____/ \___|_| |_| .__/ \__|
81-
|_|
82-
83-
:? shows help
76+
<pre><code>PSCi, version 0.9.0
77+
Type :? for help
8478
&gt;</code></pre>
8579
<p>As the introduction indicates, you can type <code>:?</code> to see a list of commands:</p>
8680
<pre><code>The following commands are available:
@@ -89,8 +83,6 @@ <h4 id="working-in-psci">Working in PSCI</h4>
8983
:quit Quit PSCi
9084
:reset Discard all imported modules and declared bindings
9185
:browse &lt;module&gt; See all functions in &lt;module&gt;
92-
:load &lt;file&gt; Load &lt;file&gt; for importing
93-
:foreign &lt;file&gt; Load foreign module &lt;file&gt;
9486
:type &lt;expr&gt; Show the type of &lt;expr&gt;
9587
:kind &lt;type&gt; Show the kind of &lt;type&gt;
9688
:show import Show all imported modules
@@ -100,12 +92,15 @@ <h4 id="working-in-psci">Working in PSCI</h4>
10092
--&gt; https://github.com/purescript/purescript/wiki/psci</code></pre>
10193
<p>We will use a selection of these commands during this tutorial.</p>
10294
<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>
103-
<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>
104-
<pre><code>&gt; :type Prelude.map
95+
<p>To see the type of one of these values, first import the appropriate module using the <code>import</code> command. Then, use the <code>:type</code> command, followed by a space, followed by the name of the value:</p>
96+
<pre><code>&gt; import Prelude
97+
&gt; :type map
10598
forall a b f. (Prelude.Functor f) =&gt; (a -&gt; b) -&gt; f a -&gt; f b
106-
&gt; :type Data.List.zip
99+
100+
&gt; import Data.List
101+
&gt; :type zip
107102
forall a b. Data.List.List a -&gt; Data.List.List b -&gt; Data.List.List (Data.Tuple.Tuple a b)</code></pre>
108-
<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>
103+
<p>We will be using some of the functions from the <code>Prelude</code> and <code>Data.List</code> modules, so make sure you have imported those by using the <code>import</code> keyword:</p>
109104
<pre><code>import Prelude
110105
import Data.List</code></pre>
111106
<p>Note that using <code>Tab</code> to autocomplete names can be a useful time-saving device in <code>psci</code>.</p>
@@ -138,7 +133,7 @@ <h4 id="solving-project-euler-1">Solving Project Euler #1</h4>
138133
<h4 id="compiling-a-solution">Compiling a Solution</h4>
139134
<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.</p>
140135
<p>Create a new text file <code>src/Euler.purs</code> and copy the following code:</p>
141-
<pre class="purescript"><code>module Euler1 where
136+
<pre class="purescript"><code>module Euler where
142137

143138
import Prelude
144139

@@ -152,7 +147,8 @@ <h4 id="compiling-a-solution">Compiling a Solution</h4>
152147
answer = sum multiples</code></pre>
153148
<p>It is possible to load this file directly into PSCi and to continue working:</p>
154149
<pre><code>pulp psci
155-
&gt; Euler1.answer
150+
&gt; import Euler
151+
&gt; answer
156152
233168
157153
&gt; :quit
158154
See ya!</code></pre>
@@ -166,7 +162,8 @@ <h4 id="writing-a-test-suite">Writing a Test Suite</h4>
166162
<pre class="purescript"><code>module Test.Main where
167163

168164
import Prelude
169-
import Euler1 (answer)
165+
166+
import Euler (answer)
170167
import Test.Assert (assert)
171168

172169
main = do
@@ -178,14 +175,15 @@ <h4 id="creating-executables">Creating Executables</h4>
178175
<pre class="purescript"><code>module Main where
179176

180177
import Prelude
181-
import Euler1
182-
import Control.Monad.Eff.Console
178+
179+
import Euler (answer)
180+
import Control.Monad.Eff.Console (log)
183181

184182
main = do
185-
log (&quot;The answer is &quot; ++ show answer)</code></pre>
183+
log (&quot;The answer is &quot; &lt;&gt; show answer)</code></pre>
186184
<p>The <code>pulp run</code> command can be used to compile and run the <code>Main</code> module:</p>
187185
<pre><code>&gt; pulp run
188-
* Building project in /Users/paf31/Documents/Code/purescript/pulp-test
186+
* Building project in pulp-test
189187
* Build successful.
190188
The answer is 233168</code></pre>
191189
<h4 id="conclusion">Conclusion</h4>

0 commit comments

Comments
 (0)