実例によるPureScript

ウェブのための関数型プログラミング

Phil Freeman, "PureScript by Example - Functional Programming for the Web"

目次に戻る

第2章 開発環境の準備

2.1 この章の目標

この章の目標は、作業用のPureScript開発環境を準備し、最初のPureScriptプログラムを書くことです。

これから書く最初のコードはごく単純なPureScriptライブラリで、直角三角形の対角線の長さを計算する関数ひとつだけを提供します。

2.2 導入

PureScript開発環境を準備するために、次のツールを使います。

この章ではこれらのツールのインストール方法と設定を説明します。

2.3 PureScriptのインストール

PureScriptコンパイラをインストールするときにお勧めなのは、PureScriptのウェブサイトからバイナリ配布物としてダウンロードする方法です。PureScriptコンパイラおよび関連する実行ファイルが、パス上で利用できるかどうか確認をしてください。試しに、コマンドラインでPureScriptコンパイラを実行してみましょう。

$ purs

PureScriptコンパイラをインストールする他の選択肢としては、次のようなものがあります。

2.4 各ツールのインストール

もしNodeJSがインストールされていないなら、NodeJSをインストールする必要があります。そうするとシステムに npmパッケージマネージャもインストールされるはずです。 npmがインストールされ、パス上で利用可能であることを確認してください。

npmがインストールされたら、 pulpbowerもインストールする必要があります。プロジェクトがどこで作業しているかにかかわらずこれらのコマンドラインツールが利用可能であるようにするため、通常はグローバルにインストールしておくのがいいでしょう。

$ npm install -g pulp bower

これで、最初のPureScriptプロジェクトを作成するために必要なすべてのツールの用意ができたことになります。

2.5 Hello, PureScript!

まずはシンプルに始めましょう。PureScriptコンパイラpulpを直接使用して、基本的なHello World! プログラムをコンパイルします。 最初に空のディレクトリmy-projectを作成し、そこでpulp initを実行します。

$ mkdir my-project
$ cd my-project
$ pulp init

* Generating project skeleton in ~/my-project

$ ls

bower.json	src		test

Pulpはsrctestという2つのディレクトリと設定ファイルbower.jsonを作成してくれます。srcディレクトリにはソースコードファイルを保存し、testディレクトリにはテストコードファイルを保存します。testディレクトリはこの本の後半で使います。

src/Main.pursという名前のファイルに、以下のコードを貼り付けてください。

module Main where

import Control.Monad.Eff.Console

main = log "Hello, World!"

これは小さなサンプルコードですが、​​いくつかの重要な概念を示しています。

それではこのコードをビルドして実行してみましょう。次のコマンドを実行します。

$ pulp run

* Building project in ~/my-project
* Build successful.
Hello, World!

おめでとうございます! はじめてPureScriptで作成されたプログラムのコンパイルと実行ができました。

2.6 ブラウザ向けのコンパイル

Pulpは pulp browserifyを実行して、PureScriptコードをブラウザで使うことに適したJavaScriptに変換することができます。

$ pulp browserify

* Browserifying project in ~/my-project
* Building project in ~/my-project
* Build successful.
* Browserifying...

これに続いて、大量のJavaScriptコードがコンソールに表示されます。 これはBrowserifyの出力で、Preludeと呼ばれる標準のPureScriptライブラリに加え、srcディレクトリのコードにも適用されます。このJavaScriptコードをファイルに保存し、HTML文書に含めることもできます。これを試しに実行してみると、ブラウザのコンソールに"Hello、World!"という文章が出力されます。

2.7 使用されていないコードを取り除く

Pulpは代替コマンド pulp buildを提供しています。 -Oオプションで未使用コードの削除を適用すると、不要なJavaScriptを出力から取り除くことができます。

$ pulp build -O --to output.js

* Building project in ~/my-project
* Build successful.
* Bundling Javascript...
* Bundled.

この場合も、生成されたコードはHTML文書で使用できます。 output.jsを開くと、次のようなコンパイルされたモジュールがいくつか表示されます。

(function(exports) {
  "use strict";

  var Control_Monad_Eff_Console = PS["Control.Monad.Eff.Console"];

  var main = Control_Monad_Eff_Console.log("Hello, World!");
  exports["main"] = main;
})(PS["Main"] = PS["Main"] || {});

ここでPureScriptコンパイラがJavaScriptコードを生成する方法の要点が示されています。

PureScriptはシンプルで理解しやすいコードを生成すること重視しているので、これらの点は大切です。実際に、ほとんどのコード生成処理はごく軽い変換です。PureScriptについての理解が比較的浅くても、ある入力からどのようなJavaScriptコードが生成されるかを予測することは難しくありません。

2.8 CommonJSモジュールのコンパイル

pulpは、PureScriptコードからCommonJSモジュールを生成するためにも使用できます。 これは、NodeJSを使用する場合やCommonJSモジュールを使用してコードを小さなコンポーネントに分割する大きなプロジェクトを開発する場合に便利です。

CommonJSモジュールをビルドするには、( -Oオプションなしで) pulp buildコマンドを使います。

$ pulp build

* Building project in ~/my-project
* Build successful.

生成されたモジュールはデフォルトで outputディレクトリに置かれます。 各PureScriptモジュールは、それ自身のサブディレクトリにある独自のCommonJSモジュールにコンパイルされます。

2.9 Bowerによる依存関係の追跡

この章の目的となっている diagonal関数を書くためには、平方根を計算できるようにする必要があります。 purescript-mathパッケージにはJavaScriptの Mathオブジェクトのプロパティとして定義されている関数の型定義が含まれていますので、 purescript-mathパッケージをインストールしてみましょう。 npmの依存関係でやったのと同じように、次のようにコマンドラインに入力すると直接このパッケージをダウンロードできます。

$ bower install purescript-math --save

--saveオプションは依存関係を bower.json設定ファイルに追加させます。

purescript-mathライブラリは、依存するライブラリと一緒に bower_componentsサブディレクトリにインストールされます。

2.10 対角線の長さの計算

それでは外部ライブラリの関数を使用する例として diagonal関数を書いてみましょう。

まず、 src/Main.pursファイルの先頭に次の行を追加し、 Mathモジュールをインポートします。

import Math (sqrt)

また、数値の加算や乗算のようなごく基本的な演算を定義する Preludeモジュールをインポートすることも必要です。

import Prelude

そして、次のように diagonal関数を定義します。

diagonal w h = sqrt (w * w + h * h)

この関数の型を定義する必要はないことに注意してください。 diagonalは2つの数を取り数を返す関数である、とコンパイラは推論することができます。しかし、ドキュメントとしても役立つので、通常は型注釈を提供しておくことをお勧めします。

それでは、新しい diagonal関数を使うように main関数も変更してみましょう。

main = logShow (diagonal 3.0 4.0)

pulp runを使用して、モジュールを再コンパイルします。

$ pulp run

* Building project in ~/my-project
* Build successful.
5.0

2.11 対話式処理系を使用したコードのテスト

PureScriptコンパイラには PSCiと呼ばれる対話式のREPL(Read-eval-print loop)が付属しています。 PSCiはコードをテストなど思いついたことを試すのにとても便利です。それでは、 psciを使って diagonal関数をテストしてみましょう。

pulp replコマンドを使ってソースモジュールを自動的に PSCiにロードすることができます。

$ pulp repl
>

コマンドの一覧を見るには、 :?と入力します。

> :?
The following commands are available:

    :?                        Show this help menu
    :quit                     Quit PSCi
    :reset                    Reset
    :browse           Browse 
    :type               Show the type of 
    :kind               Show the kind of 
    :show        import       Show imported modules
    :show        loaded       Show loaded modules
    :paste       paste        Enter multiple lines, terminated by ^D

Tabキーを押すと、自分のコードで利用可能なすべての関数、及びBowerの依存関係とプレリュードモジュールのリストをすべて見ることができるはずです。

Preludeモジュールを読み込んでください。

> import Prelude

幾つか数式を評価してみてください。 PSCiで評価を行うには、1行以上の式を入力し、Ctrl+ Dで入力を終了します。

> 1 + 2
3

> "Hello, " <> "World!"
"Hello, World!"

それでは PSCidiagonal関数を試してみましょう。

> import Main
> diagonal 5.0 12.0

13.0

また、 PSCiで関数を定義することもできます。

> double x = x * 2

> double 10
20

コード例の構文がまだよくわからなくても心配はいりません。 この本を読み進めるうちにわかるようになっていきます。

最後に、 :typeコマンドを使うと式の型を確認することができます。

> :type true
Boolean

> :type [1, 2, 3]
Array Int

PSCiで試してみてください。もしどこかでつまずいた場合は、メモリ内にあるコンパイル済みのすべてのモジュールをアンロードするリセットコマンド :resetを使用してみてください。

演習

  1. (簡単) Mathモジュールで定義されている pi定数を使用し、指定された半径の円の面積を計算する関数 circleAreaを書いてみましょう。また、 PSCiを使用してその関数をテストしてください。 (ヒントimport math文を修正して、 piをインポートすることを忘れないようにしましょう)
  2. (やや難しい) purescript-globalsパッケージを依存関係としてインストールするには、bower installを使います。PSCiでその機能を試してみてください。 (ヒント: PSCiの :browseコマンドを使うと、モジュールの内容を閲覧することができます)

まとめ

この章では、Pulpツールを使用して簡単なPureScriptプロジェクトを設定しました。

また、最初のPureScript関数を書き、コンパイルし、NodeJSを使用して実行することができました。

以降の章では、コードをコンパイルやデバッグ、テストするためにこの開発設定を使用しますので、これらのツールや使用手順に十分習熟しておくとよいでしょう。

目次に戻る