Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions _site/download/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,28 @@ <h2>Homebrew</h2>

<h2>Stack</h2>

<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>
<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>

<p>Update the Hackage package index:</p>
<pre>
stack install purescript --resolver=nightly
</pre>
stack update</pre>

<p>Download the latest source distribution and place it into a new directory in the current directory:</p>
<pre>
stack unpack purescript</pre>

<p>Compile and install PureScript:</p>
<pre>
cd purescript-x.y.z # (replace x.y.z with whichever version you just downloaded)
stack install</pre>

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

<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>

<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>
<pre>
stack unpack purescript-0.8.5</pre>
</section>

<section>
Expand Down
68 changes: 35 additions & 33 deletions _site/learn/eff/index.html

Large diffs are not rendered by default.

23 changes: 9 additions & 14 deletions _site/learn/ffi/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ <h4 id="calling-purescript-from-javascript">Calling PureScript from Javascript</
<p>Let’s take the following simple module as an example:</p>
<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>

<span class="kw">import </span><span class="dt">Prelude</span>

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>
gcd n m <span class="fu">|</span> n <span class="fu">==</span> <span class="dv">0</span> <span class="fu">=</span> m
gcd n m <span class="fu">|</span> m <span class="fu">==</span> <span class="dv">0</span> <span class="fu">=</span> n
Expand All @@ -69,28 +71,22 @@ <h4 id="understanding-name-generation">Understanding Name Generation</h4>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell">example' <span class="fu">=</span> <span class="dv">100</span></code></pre></div>
<p>generates the following Javascript:</p>
<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>
<p>This scheme also applies to names of infix operators:</p>
<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>
<p>generates</p>
<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>
<h4 id="calling-javascript-from-purescript">Calling Javascript from PureScript</h4>
<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>
<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>
<h4 id="foreign-modules">Foreign Modules</h4>
<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>
<ul>
<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>
<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>
<li>All exports must be of the form <code>exports.name = value;</code>, specified at the top level.</li>
</ul>
<p>Here is an example, where we export a function which computes interest amounts from a foreign module:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="st">&quot;use strict&quot;</span><span class="op">;</span>

<span class="co">// module Interest</span>

<span class="va">exports</span>.<span class="at">calculateInterest</span> <span class="op">=</span> <span class="kw">function</span>(amount) <span class="op">{</span>
<span class="cf">return</span> amount <span class="op">*</span> <span class="fl">0.1</span><span class="op">;</span>
<span class="op">};</span></code></pre></div>
<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>
<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>
<pre class="purescript"><code>module Interest where

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

<span class="co">// module Interest</span>

<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>
<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>
<span class="op">};</span></code></pre></div>
<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>
<pre class="purescript"><code>module Interest where

import Data.Function (Fn2)

foreign import calculateInterest :: Fn2 Number Number Number</code></pre>
<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>
<pre class="purescript"><code>calculateInterestCurried :: Number -&gt; Number -&gt; Number
calculateInterestCurried = runFn2 calculateInterest</code></pre>
<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>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="st">&quot;use strict&quot;</span><span class="op">;</span>

<span class="co">// module Interest</span>

<span class="va">exports</span>.<span class="at">calculateInterest</span> <span class="op">=</span> <span class="kw">function</span>(amount) <span class="op">{</span>
<span class="cf">return</span> <span class="kw">function</span>(months) <span class="op">{</span>
<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>
Expand All @@ -129,9 +123,10 @@ <h4 id="handling-constrained-types">Handling Constrained Types</h4>
<p>For example, let’s write a simple PureScript function with a constrained type, and look at the generated Javascript.</p>
<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>

<span class="kw">import </span><span class="dt">Data.Tuple</span>
<span class="kw">import </span><span class="dt">Prelude</span>
<span class="kw">import </span><span class="dt">Data.Tuple</span> (<span class="dt">Tuple</span>(..))

<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
<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
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
inOrder a1 a2 <span class="fu">=</span> <span class="dt">Tuple</span> a2 a1</code></pre></div>
<p>The generated Javascript looks like this:</p>
Expand Down
6 changes: 3 additions & 3 deletions _site/learn/generic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ <h4 id="generics-overview">Generics Overview</h4>
<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>
<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>
<span class="ot"> toSignature ::</span> <span class="dt">Proxy</span> a <span class="ot">-&gt;</span> <span class="dt">GenericSignature</span>
<span class="ot"> toSpine ::</span> a <span class="ot">-&gt;</span> <span class="dt">GenericSpine</span>
<span class="ot"> fromSpine ::</span> <span class="dt">GenericSpine</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</code></pre></div>
<span class="ot"> toSpine ::</span> a <span class="ot">-&gt;</span> <span class="dt">GenericSpine</span>
<span class="ot"> fromSpine ::</span> <span class="dt">GenericSpine</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</code></pre></div>
<p><code>Generic</code> defines three functions:</p>
<ul>
<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>
Expand Down Expand Up @@ -85,7 +85,7 @@ <h4 id="handling-foreign-data">Handling Foreign Data</h4>
return <span class="fu">$</span> <span class="dt">Person</span> { name, location }</code></pre></div>
<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>
<p>The <code>purescript-foreign-generic</code> library defines a function <code>readGeneric</code>, with the following type:</p>
<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>
<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>
<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>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">myOptions ::</span> <span class="dt">Options</span>
myOptions <span class="fu">=</span> defaultOptions { unwrapNewtypes <span class="fu">=</span> true }</code></pre></div>
Expand Down
42 changes: 20 additions & 22 deletions _site/learn/getting-started/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ <h2>Menu</h2>
<main>
<section class="article">
<h2>Getting Started with PureScript</h2>
<div class="meta">By Phil Freeman, published on December 13, 2015</div>
<div class="meta">By Phil Freeman, published on May 24, 2016</div>

<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>
<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>
Expand Down Expand Up @@ -73,14 +73,8 @@ <h4 id="installing-dependencies">Installing Dependencies</h4>
<h4 id="working-in-psci">Working in PSCI</h4>
<p>PSCi is the interactive mode of PureScript. It is useful for working with pure computations, and for testing ideas.</p>
<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>
<pre><code> ____ ____ _ _
| _ \ _ _ _ __ ___/ ___| ___ _ __(_)_ __ | |_
| |_) | | | | '__/ _ \___ \ / __| '__| | '_ \| __|
| __/| |_| | | | __/___) | (__| | | | |_) | |_
|_| \__,_|_| \___|____/ \___|_| |_| .__/ \__|
|_|

:? shows help
<pre><code>PSCi, version 0.9.0
Type :? for help
&gt;</code></pre>
<p>As the introduction indicates, you can type <code>:?</code> to see a list of commands:</p>
<pre><code>The following commands are available:
Expand All @@ -89,8 +83,6 @@ <h4 id="working-in-psci">Working in PSCI</h4>
:quit Quit PSCi
:reset Discard all imported modules and declared bindings
:browse &lt;module&gt; See all functions in &lt;module&gt;
:load &lt;file&gt; Load &lt;file&gt; for importing
:foreign &lt;file&gt; Load foreign module &lt;file&gt;
:type &lt;expr&gt; Show the type of &lt;expr&gt;
:kind &lt;type&gt; Show the kind of &lt;type&gt;
:show import Show all imported modules
Expand All @@ -100,12 +92,15 @@ <h4 id="working-in-psci">Working in PSCI</h4>
--&gt; https://github.com/purescript/purescript/wiki/psci</code></pre>
<p>We will use a selection of these commands during this tutorial.</p>
<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>
<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>
<pre><code>&gt; :type Prelude.map
<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>
<pre><code>&gt; import Prelude
&gt; :type map
forall a b f. (Prelude.Functor f) =&gt; (a -&gt; b) -&gt; f a -&gt; f b
&gt; :type Data.List.zip

&gt; import Data.List
&gt; :type zip
forall a b. Data.List.List a -&gt; Data.List.List b -&gt; Data.List.List (Data.Tuple.Tuple a b)</code></pre>
<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>
<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>
<pre><code>import Prelude
import Data.List</code></pre>
<p>Note that using <code>Tab</code> to autocomplete names can be a useful time-saving device in <code>psci</code>.</p>
Expand Down Expand Up @@ -138,7 +133,7 @@ <h4 id="solving-project-euler-1">Solving Project Euler #1</h4>
<h4 id="compiling-a-solution">Compiling a Solution</h4>
<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>
<p>Create a new text file <code>src/Euler.purs</code> and copy the following code:</p>
<pre class="purescript"><code>module Euler1 where
<pre class="purescript"><code>module Euler where

import Prelude

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

import Prelude
import Euler1 (answer)

import Euler (answer)
import Test.Assert (assert)

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

import Prelude
import Euler1
import Control.Monad.Eff.Console

import Euler (answer)
import Control.Monad.Eff.Console (log)

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