Haskellは純粋関数型プログラミング言語です。本連載では既にLispやOCamlなどの関数型言語を紹介しましたが、Haskellは関数型言語の中でも特に人気の高い言語です。Stack Overflowの人気言語調査でも2020年は15位、2021年は22位と人気言語がひしめくなか健闘しています。Haskellは難しい言語としても有名ですが、その作法を学ぶならプログラマーの基礎体力の向上に役立つことでしょう。今回はHaskellを試してみよう。
Haskellとは
Haskellは関数型プログラミング言語の一つです。 純粋関数型言語に分類されます。金融やセキュリティ、科学解析、プログラミング言語の開発などの分野で使われています。総じて信頼性が求められる分野の開発で採用されています。そのため、十分実用的な言語と言えます。
しかし、Haskellには「遅延評価」や「モナド」などの概念があり難しい言語であると思われています。それでも、こうしたHaskellプログラミングに欠かせない考え方を学ぶことでプログラミングスキルの向上に役立ちます。ちなみに、Haskellという名前は、数学者であり論理学者のハスケル・カリーに由来しています。
Haskellの歴史
Haskellは1990年に登場した言語です。Haskellの誕生に深く関わっているのが純粋関数型プログラミング言語「Miranda」です。Mirandaは1985年にリサーチソフトウェア社から発表され広く使われました。ところが、ライセンスがオープンなものではありませんでした。そこで、1987年に開催されたFPCA '87会議において、オープンソースな言語を開発されるべきという意見が出て、Haskell開発のための委員会が発足し開発が始まりました。
そして、1990年に最初のバージョンが作成されました。その後、1999年には学習用および将来の拡張の基礎として、基本ライブラリなどを定義したHaskell 98 が登場しました。その後、2009年には他のプログラミング言語と組み合わせて使えるように改良された、Haskell 2010が登場しました。
Haskellのインストール
それでは、Haskellをインストールして実際に動かしてみましょう。WindowsとmacOSに分けて手順を紹介します。
【Windows】
WindowsでHaskellをインストールするには、PowerShellからコマンド入力でアプリをインストールできる「Chocolatey」を使います。Chocolateyのインストール方法は、こちらに書かれています。
簡単に書くと、管理者権限でPowerShellを起動し、以下のコマンドを実行します。
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
無事にChocolateyが導入できたら、以下のコマンドを実行しましょう。
choco install haskell-dev
refreshenv
【macOS】
macOSでは、Homebrewを使うと手軽にインストールできます。最初に、stackをインストールし、stackを利用してGHCを導入します。
$ brew install stack
$ stack setup
その他のLinuxへのインストールについては、こちらに詳しく書かれています。
一番簡単なプログラムを実行してみよう
上記の手順でHaskellをインストールすると、GHCというHaskellコンパイラが使えるようになります。(macOSの場合は、stackというビルドツールがインストールされます。)
Haskellで画面に「Hello, World!」と表示するプログラムは、次のようになります。1行だけのプログラムです。テキストエディタでプログラムを記述したら、「hello.hs」という名前で保存しましょう。(文字コードはUTF-8で保存しましょう。)
main = putStrLn "Hello, World!"
そして、PowerShellやターミナルで以下のコマンドを実行します。すると「Hello, World!」と画面に出力されます。(なお、macOSで上記手順でstackをインストールした場合は、「ghc」を「stack ghc」と読み替えてください。)
# コンパイル
ghc hello.hs
# 実行
.¥hello
プログラムを見ていきましょう。Haskellのプログラムはmain関数からはじまります。それで、「main = 関数の内容」のように記述します。ここからHaskellで関数を定義するには「関数名 = 関数内容」と書くことも分かります。関数型プログラミング言語と言われる通り、気軽に関数が記述できるのが良いところです。
FizzBuzz問題のプログラムを作ってみよう
続いて、本連載で毎回作っているFizzBuzz問題を解くプログラムを作ってみましょう。FizzBuzz問題とは次のような課題です。
> 1から100までの数字を出力してください。その際、3の倍数の時「Fizz」、5の倍数の時「Buzz」、3と5の倍数の時「FizzBuzz」と表示するプログラムを作って下さい。
Haskellを使ってどのように解くことができるでしょうか。以下のプログラムを「fizzbuzz.hs」という名前で保存しましょう。
-- FizzBuzzの挙動を定義 --- (*1)
fizzbuzz :: Int -> String
fizzbuzz n | n `mod` 15 == 0 = "FizzBuzz"
| n `mod` 3 == 0 = "Fizz"
| n `mod` 5 == 0 = "Buzz"
| otherwise = show n
-- 1から100まで連続でfizzbuzzを呼び出す --- (*2)
main = do
mapM_ putStrLn $ map fizzbuzz [1..100]
コンパイルして実行してみましょう。(先ほどと同様に、macOSでは「ghc」を「stack ghc」と読み替えてください。)
ghc fizzbuzz.hs
.¥fizzbuzz
すると、1から100までのFizzBuzzの値が出力されます。
なお、Haskellで一行コメントを表すのが「-- コメント」です。Haskellはコメント記号も独特で面白いですね。それでは、プログラムを詳しく見ていきましょう。
プログラムの(*1)の部分で引数nに対するFizzBuzzの値を判定して返す関数を定義します。「fizzbuzz :: Int -> String」の部分でfizzbuzzという関数の型を定義します。ここでは、Int型の引数を得てString型を返すという意味になります。そして、次の行以降では、`mod`を利用して、nを割った余りが0になる(つまり、割り切れる)場合にFizzBuzzの各条件に応じた値を返すようにします。
(*2)では1から100まで順に関数fizzbuzzを呼び出してFizzBuzzの答えを得た上で、それを順にputStrLnで一行ずつ出力します。
なお、(*1)で利用した「|」はガード条件という構文で以下のような書式で記述できるようになっています。次々と条件をチェックすることができる便利な構文です。
関数名 引数1, 引数2, 引数3, ...
| 条件1 = 結果1
| 条件2 = 結果2
| 条件3 = 結果3
| otherwise = その他結果
まとめ
以上、今回は簡単にHaskellについて紹介しました。今回見たとおり、JavaScriptやPythonなどの言語しか知らないと、Haskellのプログラムは少し奇怪に見えるかもしれません。しかし、その構文を一つずつ確認していくなら、それほど難しいものではないのかもしれません。ゆっくりとHaskellを学んでそのエッセンスを学んでみるのはどうでしょうか。きっとプログラマーの基礎体力を向上させることができるでしょう。
自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。直近では、「シゴトがはかどる Python自動処理の教科書(マイナビ出版)」「すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応(ソシム)」「マンガでざっくり学ぶPython(マイナビ出版)」など。