なぜHaskellを学ぶと良いか

## なぜこれを書くのか

私がQiitaに投稿した記事を見た方から、メールが届きました。
プログラミング言語のHaskellを勉強し始めたものの、難しくてやめようかと考えているそうです。

その気持ちも非常によく分かります。
[すごいH本](http://www.amazon.co.jp/gp/product/4274068854/ref=as_li_tf_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4274068854&linkCode=as2&tag=qaec01-22)が出版されてから年月も経ち、それなりに勉強しやすくなったとはいえ、お世辞にもHaskellを学ぶ環境が整っているとは言えません。

私はHaskellで製品開発をする会社**を**保守運用していたことがあり、また自分自身もHaskellでプログラムを書いています。
また、Haskellを普及させるべく、「[こわくないHaskell入門](http://qiita.com/arowM/items/9ebfb7cafecd99290663)」という記事を書いたこともあります。
これらの経験を踏まえ、この機会にあらためて「なぜHaskellを学ぶと良いか」についてまとめたいと思い立ちました。

Haskellについてまだよく知らない方が、入り口として読める内容を目的としているので、できるだけ専門用語を使いませんし、厳密な言葉の定義なども極力省きます。
また、この記事は「なぜHaskellを学ぶと良いか」であり、「なぜ他の言語よりもHaskellを使うべきか」について多くは語りません。
もし後者について知りたければ、末尾の[なぜ他の言語よりもHaskellを使うべきか](#なぜ他の言語よりもhaskellを使うべきか)をご参照いただくか、ググればいくらでも情報が手に入ります。

みずから一歩を踏み出し、Haskellを学ぼうと決めた方に、「Haskellには時間を投資する価値があるんだ」と自信をもっていただくための内容です。

## まずHaskellへの誤解を解こう

私に送られたメールは

> 関数型言語は手続き型と比較していいものですか？

と問いかけるものでした。

実はこの質問に、多くのHaskell初学者がつまづく誤解が潜んでいます。
その誤解されがちなHaskellの真実は次のとおりです。

1. Haskellは関数型言語だから優れているのではない
2. Haskellは手続き型でもある
3. Haskellでは手続き型な書き方もよく使う

まずは、この3つの事実について詳しく考察しましょう。


### 1. Haskellは関数型言語だから優れているのではない

Haskellは、関数型言語という特徴を、よく前面に押し出されて紹介されます。
もしかしたら、あなたは「関数型言語」を勉強するためにHaskellを始めたかもしれません。
世の中には「関数型」というキャッチーな言葉を利用して、誤りだらけの本を出版した方もいらっしゃいますしね！[^2]

しかし、Haskellが魅力的なのは、それが関数型言語だからではないという点です。
たとえば、オーパーツであるLispという言語も「関数型」ですが、LispとHaskellとはまるで異なる魅力を持っています。

Lispを知らないあなたに例え話でお伝えします。
猫ちゃん大好き人間は、猫ちゃんが「食肉目」であるところに魅力を感じるのでしょうか？
同じ食肉目であるワンちゃんとは、別の魅力がたくさんあるはずです。
ちなみに私は鯨偶蹄目のヤギさんが好きなので、ヤギさんを飼えるお家に引っ越しました。

### 2. Haskellは手続き型でもある

そうは言っても、Haskellが関数型な性質を持っているのは確かで、それを学ぶのに苦労する方が多いことも事実です。
ですが、関数型であることは、Haskellを魅力づける特徴の中のたった1つですから、学ぶのを後回しにすれば良いのです。

[こわくないHaskell入門](http://qiita.com/arowM/items/9ebfb7cafecd99290663)の内容がまさにそれですが、Haskellは手続き型のスタイルで記述することもできます。
もちろん、オブジェクト指向についても、@fumieval さんなどが多くの知見を発表されていますし、なんなら工夫すれば[Forth](https://ja.wikipedia.org/wiki/Forth)みたいなスタック指向プログラミングだってできるんじゃないでしょうか。

もし、関数型な部分を学ぶのを後回しにするのが難しいのならば、まずあなたが普段から使っている言語で関数型なスタイルを学んでから再挑戦しましょう。

### 3. Haskellでは手続き型な書き方もよく使う

ここで、手続き型スタイルのHaskellプログラミングを実世界のアプリケーション開発でもよく使うことを示します。
このサンプルプログラムを見てみてください。

```haskell
-- | Web API が提供されているブログサービスから記事を取得したり、
--   投稿したりするサンプルプログラム
main :: IO ()
main = myHandler do
  -- Web API を使うためのtokenを取得する
  token <- getToken
  -- 全記事内容を取得する
  posts <- getPosts token
  let
    -- 自分が筆者になっている記事のみを抽出する
    myPosts = filter isMyPost posts
    -- 自分が筆者になっている記事のIDのみを抽出する
    myPostIds = map postId myPosts
    -- 自分が筆者になっている記事のIDが並んでいる文字列に変換する
    body = unlines myPostIds
  -- 自分が筆者として、記事ID一覧が書かれた記事を投稿する
  postMyPosts "my post list" body
```

これはHaskellですが、全体的に手続き型っぽいですよね？
（詳しく文法を理解しようとする必要はありません。雰囲気を感じとってください）
変にすべてを「関数型」スタイルで記述するよりも、こうやって命令を順番に組み合わせたほうが、プログラムの急な仕様変更等にも柔軟に対応できます。

この中で「関数型」と言われるのは`map`とか`filter`のような関数だけです。
これらの関数は、JavaScriptなど、あなたの普段づかいの言語にも含まれているはずです。

## Haskellを学べば他言語の書き方が変わる

さて、Haskellへの誤解を解いたところで、Haskellを学ぶことのメリットを話しましょう。
なんと言っても、Haskellを学ぶことで、Haskell以外のプログラミング言語の書き方が大きく改善されます。

Haskellは **できることが制限された** 言語です。
そう聞くとデメリットのようですが、すなわち **アンチパターンを実装しにくい** 言語です。
そして、**いい書き方を強要する** 言語です。

たとえば、Haskellを学んだ人は、テストしやすいプログラムを書くようになるでしょう。
ここでは詳しく説明しませんが、「純粋な関数と、純粋でない関数の明確な区別」という言語特性があるからです。

他の恩恵として、可読性の高いプログラムを書くようになるでしょう。
こちらも詳しくは省きますが、純粋な関数内で変数への値の再代入ができないことや、ドキュメントの役割をになう型表記、柔軟な抽象化機能などのおかげです。

それ以外にも、実行速度やメモリ使用量を意識したプログラムを書くようになるでしょう。
単方向リストやさまざまなデータ構造のライブラリのドキュメントを読んだり、自分で柔軟にデータ型を作成する中で計算量に触れる場面が多いからです。

しかし、これらは本来他の言語、とりわけあなたの普段づかいの言語で学んでおくべき内容です。
逆にあなたが普段づかいの言語をよく学んでいれば、Haskellを学んでいてつまづくことは少ないはずです。
Haskellを学んでいて「難しい」と感じたのならば、それは普段づかいの言語で苦労して学ぶべきことを、Haskellが代わりに教えてくれているのかもしれません。

## Haskellを学ぶと人生が変わる

Haskellを学ぶことは、プログラミング以外でもあなたの人生を豊かにします。

Haskellの重要な特性の1つに「抽象化」があります。
抽象化によってプログラムの可読性、保守性を大きく向上できます。
一見異なる事象の間に共通する部分を見つける能力が抽象化力です。
ここで磨かれた抽象化力をさらに高めて、プログラミング以外の世界にもHaskellを応用すれば良いのです。

新しいプログラミングの考え方を学ぶ経験を通して、今までにやったことがない新しい物事の習得の仕方を学ぶことができるでしょう。
私も会社の保守運用の方法を学ぶ際に大きく役に立ちました。
Haskellを学べば、もしこの世の中からプログラマが必要なくなったとしても、職に困ることはありません。

今までの自分にはできなかったことを、自分の力で努力してできるようになる体験を通して、「いつも口先だけで実際には何にもできないウンコみたいな意識高いだけ系クズ」な人間を見抜く力が身につくでしょう。
ウンコ人間に騙されなくなります。

コンパイラに何度も「お前、これ何の型かわかんないんだけど？？」と怒られる経験を通して、日頃のコミュニケーションでも相手が理解できるように適切に自分の意図する内容を伝えることができるようになるでしょう。
これで異性にもモテモテです。

## 6年後からの追記

この記事を執筆してから6年が経ち、私やHaskell、世界を取り巻く状況も変わりました。
ここで述べた内容は本質に関わる部分なので、基本的には6年経った今でも変わりません。

ただ、Haskellは「たくさんのことができる言語」という方向にどんどん進んでいるように感じます。
汎用言語である以上それもひとつの価値ですし、コミュニティで運営しているゆえに機能が膨れ上がることも仕方のない面もあります。歴史が長いぶん、様々なしがらみに縛られることも仕方のないことです。
私自身もまだHaskellを仕事で使っていますが、上記で述べたような恩恵を受けたいのであればElmを学ぶことを検討してみてもいいかもしれません。

Elmはウェブアプリケーションのフロントエンドにしか使えない汎用性のない言語です。
しかしその性質ゆえに多くの恩恵を我々にもたらします。その恩恵の1つとして、上述の「できることが制限された言語」という要素はHaskellを凌駕します。
できることはHaskellよりも限られますが、一方で学ぶことで得られるプログラミング観の変化はHaskell以上かもしれません。
Elmについては「[Elm入門の入門 最初に読むページ](https://qiita.com/arowM/items/5ec5853298fc880353b7)」をご覧ください。

## なぜ他の言語よりもHaskellを使うべきか

この記事で、Haskellへの誤解を解いたところで、次のステップとして、以下の記事を見てみてもいいでしょう。
Haskellが他の言語に比べて、どういう場合に優位であるか（あるいは適していないか）が分かります。
ただ、いつまでもHaskellに関する特徴を説明する記事を読んでいるばかりで、実際に書き始めないのであれば、「いつも口先だけで実際には何にもできないウンコみたいな意識高いだけ系クズ」と大差なくなってしまうので、お気をつけ下さい。

* [Why Haskell matters](https://wiki.haskell.org/Why_Haskell_matters)
* [Haskellと共に4年間を歩んだ起業家の視点](http://postd.cc/haskell-in-a-startup/)
* [なぜ我々はHaskellを使うのか](https://gist.github.com/tanakh/8750952)

また、Haskellを実際に事業に採用してみた生々しい話やヤギさんが好きな方は
[資金力のないWeb系ベンチャーがHaskellを採用したらどうなったか](https://qiita.com/arowM/items/25b7740ca0f31cc1be15)もどうぞ。

[^2]: 関数型にくわしいお父さん、お母さんに聞きましょう。