序説
Haskellは汎用の純粋関数型言語であり、近年のプログラミング言語のデザインにおける多くの革新を取り入れている。Haskellは高階関数、非正格意味論、静的多相型付け、ユーザー定義代数的データ型、パターンマッチ、リスト内法表記、モジュールシステム、モナドを用いたI/Oシステム、リスト、配列、任意精度と固定精度整数、浮動小数点数などを含む豊富な基本データ型を備えている。Haskellは非正格関数型言語に対する長年の研究の極致であり結実である。
このレポートはHaskellプログラムの文法と、それらプログラムの意味づけを行うための形式的でない抽象意味論を定義するものである。Haskellプログラムがどのように操作され、実行され、コンパイルされるかなどについては実行依存のこととしておく。このことは、プログラミング環境の特質や、未定義のプログラムに対して返却されるエラーメッセージ(すなわち、形式的には⊥に評価されるプログラム)などに関する事項を含んでいる。
プログラムの構造
このセクションでは、Haskellの大まかな文法と意味論の構造及びそれらがレポートの残りの章の構造とどのように関係しているかについて説明する。
- Haskellプログラムの一番トップレベルは5章で説明される モジュール の集合である。モジュールは名前空間の管理と大規模なプログラムにおいてソフトウェアが再利用できる手段を提供するものである。
- モジュールのトップレベルは 宣言 の集まりであり、これらは複数の種類のものからなる。すべて4章で説明される。宣言は通常の値、データ型、型クラス、結合性情報などのものを定義するものである。
- 次に来るレベルは 式 であり、3章で説明される。式は 値 を表現し、 静的型 を持つ。式は"小規模な"Haskellプログラミングにおいて中心的な役割を果たすものである。
- 一番下のレベルにくるものはHaskellの 文法構造 であり、2章で説明される。文法構造はテキストファイルに書かれたHaskellプログラムの具体的な表現を捉えるものである。
このレポートはHaskellの文法的な構造を下から上に向かって進めていく。
上で触れられていない章は、Haskellの標準的な組み込みデータ型と組み込みクラスについて説明している6章と、HaskellにおけるI/O機能(すなわち、Haskellが外の世界とどのようにやりとりするか)について述べる7章である。また、Prelude、具体的な文法、文芸的プログラミング、インスタンス導出の仕様、多くのHaskellコンパイラによってサポートされるプラグマについても章を割いている。
本文ではHaskellプログラム断片の例をタイプライターフォント(訳注: このドキュメントではタイプライターフォントまたはコードブロックとして表示する)で表示する:
let x = 1
z = x+y
in z+1
任意の部分Haskellコードを表現しているプログラム断片における「穴」はイタリック体で表示され、例えば if e1 then e2 else e3 となる。一般的にはイタリック体になっている部分はニーモニック(訳注: 覚えやすいようにそれらしい名前を付けること)であり、例えば e は式、 d は宣言、 t は型といった具合である。
Haskellのカーネル
Haskellは関数型プログラミングで有名になった多くの便利な文法構造を採用している。このレポートではそういった構文糖衣の意味はより簡単な構成に変換されて与えられる。これら変換が漏れなく適用された場合、結果としてプログラムはHaskellの小さなサブセットによって書かれたことになるが、これを我々はHaskellの カーネル と呼ぶ。
カーネルは正確に規定されたものではないが、これは本質的には標準的な表示的意味論をもつラムダ計算を少し構文糖衣によって変えたものである。各文法構造からカーネルへの変換はその文法の導入と同様にして与えることができる。このように(訳注: カーネルがHaskellから切り離されているという)設計はHaskellプログラムに対する推論を容易にし、言語の実装者に対して便利なガイドラインを提供する。
値と型
式は 値 に評価され、 静的型 を持つ。値と型はHaskellでは混合されていない。しかし、型システムは色々な種類のユーザー定義データ型を許容しており、パラメータ多相(伝統的なHindley-Milner型推論を用いている)だけでなく アドホック多相 あるいは(型クラスを用いた) オーバーロード と呼ばれるものも利用可能である。
Haskellでのエラーは意味論的には⊥ (「ボトム」)と同値である。技術的には、これは停止しないことと区別不可能であり、よって言語はエラーを検知したりそれに作用するような機構を持たない。しかし実装者はエラーに対して有用な情報を提供しようとするかもしれない。セクション3.1をみよ。
名前空間
Haskellには名前が6種類ある: 変数 と コンストラクタ の名前は値を表現し、型変数 と 型コンストラクタ と 型クラス の名前は型システムに関連したエンティティを表し、モジュール名 はモジュールを表す。名前には2つの制約がある:
- 変数と型変数の名前は小文字またはアンダースコアから始まる識別子、他の4種類の名前は大文字から始まる識別子である
- 識別子は同じスコープ内で、型コンストラクタの名前かつクラスの名前として使われてはならない
制約はこれだけである。例えば、Int
は1つのスコープで同時にモジュール、クラス、コンストラクタの名前として使われる可能性がある。