Haskell
関数名は先頭が小文字でなければならず、記号を含むことはできない。演算子名は記号のみで構成されていなければならない。関数の定義ではC言語のような引数を囲む括弧や区切りのカンマは使われず、単に引数を空白文字で区切って表記する。次は先程示した恒等関数 id に、型の定義に加えて本体の定義もした例である。
関数の適用も同様で、単に関数に続いて空白文字で区切った引数を並べればよい。以下では上記の恒等関数 id を(ここでは使う必要はないが)適用して、別の変数を定義した例である。
引数がつねに2個であることや引数の間に演算子をおくことなどを除けば、演算子についても関数の定義や適用と同様である。標準で定義されている算術演算子を使って、BMIを計算する関数 bmi を定義してみる。
この定義では Float を引数にとり Float で結果を返すが、この関数では Double を引数に使うことはできない。
(さらに、フィボナッチ数はnに対して2と大きな値になるので、そのようなBigIntegerの加算のコストも掛かり、以前にこの場所に書かれていたような「線形時間でのフィボナッチ数列の生成」は、大きい値では不可能である)
どのように評価が進行するかの例示のために、次は6つの要素の計算の後の fibs と tail fibs の値と、どのようにzipWith (+) が4つの要素を生成し、次の値を生成し続けるかを図示したものである。
次はGHCで使える言語拡張で、リスト内包表記を並列的な生成を記述できるよう拡張するParallelListCompを用いて書いた同様の式である。(GHCの拡張は特別なコマンドラインフラグ、またはLANGUAGEプラグマによって有効にしなければならない。詳しくはGHCのマニュアルを参照のこと)
先に見た階乗の定義は、次のように関数の列を内包表記で生成して書く事もできる。
特に簡潔に書ける例として、ハミング数が順番に並ぶリストを返す以下のような関数がある。
上に示されたさまざまな fibs の定義のように、これはオンデマンドに数のリストを実現するために無限リストを使っており、1 という先頭要素から後続の要素を生成している。
ここでは、後続要素の構築関数は where 節内の記号 # で表現された中置演算子で定義されている。
各|は、等号の前半の条件部分と、後半の定義部分からなるガード節を構成する。
カリー化によって、Haskell のあらゆる関数は引数を部分適用することができる。つまり、関数の引数の一部だけを渡すことで、一部の変数だけが適用された別の関数を作り出すことができる。また、Haskell では演算子を部分適用することすら可能であり、演算子の部分適用をとくにセクションと呼ぶ。
任意のリストをとり、その要素から条件にあう要素のみを取り出す関数 filter が標準ライブラリに定義されている。
この関数では第一引数に残す要素を判定する関数をとるが、このときに部分適用を使えばそのような関数を簡潔に書くことができる。整数のリストから正の値のみを取り出す関数 positives は次のように定義できる。
ここで、positives および filter の第2引数はソースコード上に現れずに記述できているが、このように単純に書けるのもカリー化の恩恵によるものである。
ここではあまり他の言語では見られない Haskell 特有の機能を中心に解説する。ここでは説明していないが、現代的な実用言語では常識となっているガーベジコレクション、例外処理、モジュール、外部関数の呼び出し、正規表現ライブラリなどの機能は、Haskell にも当然存在している。
これは新しい Haskell の方言である。開発の際の焦点は、明瞭なエラーメッセージを提供し学習を容易にすることである。Heliumは型クラスをサポートせず、多くのHaskellプログラムとは互換性のない実装である。