大学生向けHaskell入門:関数型プログラミングの世界へ

Haskellというプログラミング言語を知っているでしょうか。

これは、大規模なデータ処理や高度なアルゴリズムの実装などにおいて評価されている言語であり、学生にとって学ぶ価値のある言語だと思います。

Haskellとは

Haskellは1980年に開発されたプログラミング言語で、科学者たちが数学の問題を解くためのツールとして開発されました。

Haskellは「単純関数型言語」という、「同じ問に対しては、いつでも同じ答えを出す」という言語であり、この特徴のおかげで動作が予想しやすくエラーが出にくいのが特徴です。

数学の問題を解くためのツールとして作られたというだけありますね。

関数型プログラミングの基本

関数型プログラミングは色々な特別なルールを持っています。

まず「状況の不変性」という物があり、これは「一度作った物は変えられない」というルールです。これがある事によって、後からエラーなどが発生した際、何が起こったのかやどこで発生したのかが推測しやすくなるのです。

次に「関数の第一級オブジェクト」です。これは、プログラムの中の「関数」という命令の組み合わせセットのような物があるのですが、その関数をまるで物のよう扱い、関数を組み合わせて新しい命令を作る事ができます。

最後に、「関数の単純性と副作用の排除」というルールがあります。これは、先ほど説明した「関数」が「特定の範囲でのみ仕事をし、それ以外の場所には一切影響を与えない」というルールです。

これらの基本ルールを元に関数型プログラミングは作成されます。

少し難しいかもしれませんが、後々分かってくるので完全に理解できなくても大丈夫です。

Haskellの基本的な文法

Haskellには以下のような文法が存在ます。

データ型

  • Int(整数)
  • Float(少数)
  • Char(文字)
  • String(文字列)

例えば、xは整数という事を表す際には、「x :: Int」という風に表します。

関数定義

Haskellでは、関数(命令の組み合わせ)を作る事ができます。

sumOfTwo x u = x + y

これは「sumOfTwo」という名前の関数を作成し、その関数に2つの数字を渡すと、値の合計が返ってきます。

関数の呼び出し

先ほど作成した関数を実際に使ってみます。

subOfTwo 3 4

これにより、7という値が計算されます。

条件分岐(if)

プログラム内で、条件によってその後の処理を分ける事ができます。

isEven x = if x 'mod' 2 == 0 then "even" else "odd"

これはxが偶数なら「even」奇数なら「odd」を返す関数「isEven」を作成しています。

まず、「isEven x」という所で「関数isEvenを作成し、引数(関数が実行される際に受け取る値)をxに入れる」という命令です。

そして次に、「if x ‘mod’ 2 == 0」という部分ですが、「もし_xが_剰余演算を_2でした時_0と同じなら」という意味です。

剰余演算とは、割った余りの事を指しています。なので、12を5で剰余演算した場合は答えが2になります。

例では、2で割った時の余りが0という事なので、これは偶数を指しており、逆に0ではない(1余った場合)は奇数という事になります。

そして最後の、「then “even” else “odd”」で「そうなら_evenを返す_そうでないなら_oddを返す」という意味になり、evenまたはoddが、isEvenという関数を実行した際に帰ってる結果となります。

ループ(再起処理)

何度か同じ処理をしたい場合、「再起関数」という何度も処理を繰り返す関数(命令の組み合わせ)を使用します。

何度も繰り返すだけでは永遠に終わらないので、「こうなったら処理終わってね」という終了条件という物も付ける必要があります。

sumToN :: Int -> Int
sumToN 0 = 0
sumToN n = n + sumToN (n - 1)

少し長いですが、頑張ってみましょう。

まず「sumToN :: Int -> Int」ですが、これはsumToNという関数が、数字の引数(関数の実行時に受け取る値)を貰い、関数処理の終わり時に何かの数字を返すという宣言です。

そして次に「sumToN 0 = 0」ですが、これは受け取った値が0の場合は0を返すという処理です。

最後に「sumToN n + sumToN (n – i)」ですが、一つ上の処理(0を受け取った場合)以外の時は、受け取った値(n)に、「sumToNを新たに実行し、nよりも一つ下の数字を引数として渡した時」に戻ってくる値を足す。という内容です。

ややこしいですね。

実際にやってみると、

  • 一回目のsumToNで3を渡して実行
  • 0ではないので、3に「二回目のsumToNで2を渡して実行」で帰ってきた値を足す
  • 二回目のsumToNで、0ではないので2に「三回目のsumToNで1を渡して実行」で帰ってきた値を足す
  • 三回目のsumToNで、0ではないので1に「四回目のsumToNで0を渡して実行」で帰ってきた値を足す
  • 四回目のsumToNは0なので、0を返す
  • 三回目のsumToNに0が返ってきたので、1に0を足して返す
  • 二回目のsumToNに1が返ってきたので、2に1を足して返す
  • 一回目のsumToNに3が返ってきたので、3に3を足して返す
  • 結果として6が返ってくる

という流れになります。

とってもややこしい。

ですが、これらの概念を組み合わせてHaskellのプログラムは組まれるので、今回紹介した内容さえ理解できれば大抵のHaskellのコードは理解できると思います。

Haskellって他と比べて何か良いのか

プログラミング言語にはJavaやPythonなど色々な物がありますが、それらと比較をした際、Haskellが秀でている点は何でしょうか。

逆にこの点が無ければ、「それ、Javaでも良くね?」となってしまいますよね。

Haskellのメリットを箇条書きで紹介していきます。

  • 単純な関数言語 … 単純であり常に同じ結果を返すので安定している。
  • 強い性的型付け … 型(Int,String等)の宣言が厳しいので、エラーが起きづらい
  • 遅延評価 … 実行時に必要になる物が用意されるまで待つので、エラーが起きづらい
  • 平行性と並列性 … マシンのパワーを効率的に生かしてコードを素早く実行できる
  • 豊富なライブラリ … ライブラリ(機能の塊)が沢山あるので複雑な処理を手軽に作れる

これらの特徴があります。

単純な仕組みで動き、処理を作る際の指定も厳しいという事で、とっても安定したプログラムの実行ができ、効率的に動かせ、複雑な機能を手軽に実装できる。

これがHaskellのメリットです。

まとめ

ざっくりとHaskellについて理解できたでしょうか。

是非興味を持った際などは、書籍などを購入して学習してみて下さい。