使い捨てプログラムの作り方

自分で苦労して作ったツールは、意外に自分では使わないものだ。その時には、必要に迫られて作るのだが、しばらくすると何のプログラムだったかも、どこにファイルがあったかも忘れてしまう。自分にとってのそのプログラムを使う必要性がその時だけの一回きりのことが多いからだ。

一回きりの使い捨てプログラムをサクサクっと作って、結果が出たらプログラムのことは忘れてしまうというのは思いのほかに出番が多いのではないだろうか。

ubuntu をインストールしたら、sudo apt-get install hugs で簡単に悪名高い Haskell の処理系がインストールできてしまった。話の種にと、積読してあった『ふつうの Haskell プログラミング』(山下信夫監修 青木峯郎著)をひっぱり出してきて見比べながらいじってみたら、Haskell がある種の作業に最適な使い捨てプログラムを作れるのに気がついた。

前置きが長くなったがとにかく Haskell を動かしてみよう。端末を起動して、コマンドラインから hugs と入力すると、Hugs という Haskell のインタープリターが立ち上がる。何か、入力してみよう。

Hugs> 1.78 * 1.78 * 22
69.7048

これは身長から理想体重を計算するプログラムだ。身長178cmのひとの理想体重は69.7kgだ。こういうのは、電卓でできるのでもう少し面倒なのをやってみよう。総コレステロール220、HDLコレステロール40、中性脂肪150のひとのLDLコレステロールの値を計算してみる。

Hugs> 220 - 40 - (150 / 5.0)
150.0

何のことはない、Haskell のインタープリターは普通の数式電卓として使える。数式電卓として使っても立派に Haskell でプログラムをしていることになる。しかし、それでは芸がないので、Haskell の特徴の一つであるリストの操作をやってみよう。まず、1から100までの数の和を求めてみる。

Hugs> sum [1..100]
5050

たった、これだけで答えが出てしまう。それじゃこれの平均値はどうなるだろう。

Hugs> sum [1..100] / 100
50.5

1から10までの数の2倍の数のリストも次のようにすれば簡単に求められる。

Hugs> map (* 2) [1..10]
[2,4,6,8,10,12,14,16,18,20]

1から10までの数の平方数はどうだろうか。

Hugs> map (\n -> n * n) [1..10]
[1,4,9,16,25,36,49,64,81,100]

Haskell の一番の特徴は無限の数を扱うことができるということだ。1からはじめて奇数を列挙してみよう。

Hugs> [1,3..]
[1,3,5,7,9,11,13,15,17,19...

無限に続くので途中でCtr+Cで中断しなければならない。もちろん無限数列から一部を切り取るのは簡単だ、1から始まる奇数の初めの5個を取り出してみよう。

Hugs> take 5 [1,3..]
[1,3,5,7,9]

例題でよく出る階乗の計算は次のようになる。

Hugs> fact 5 where fact n = if n > 0 then n * fact (n-1) else 1
120

あるいはもっと直観的に、

Hugs> product [1..5]
120

フィボナッチ数の計算は次のようになる。

Hugs> take 10 fibs where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
[0,1,1,2,3,5,8,13,21,34]

長くなるのでこれくらいにするが、たいていの用事が一行で済んでしまう。圏論やらモナドやら知らなくてもこれだけでも Haskell で使い捨てのプログラムを作る理由があるのだ。要するに Haskell にはめちゃくちゃ直観的にわかりやすい部分と、逆立ちしても理解できないような難しい部分とが混在しているようだ。しかし、使い捨てのプログラムに利用すると割り切ってしまうと、結構便利だし、このタイプ量の少なさでよくこんなことができるなと嬉しくなってしまう。

難しそうで何となく避けていた Haskell だが、部分的な知識でも結構面白いことができるようだ。

追記

これは4年前の記事だ。Hugs は利用可能だが、開発が中止されている。今は、GHCが主流で GHCI のインタラクティブな操作もずいぶん改善されている。GHC は Haskell Platform のページからダウンロードできる。
[PR]
by tnomura9 | 2009-08-04 19:27 | Haskell | Comments(0)
<< Haskell のリスト操作 いまさらながらのFirefox... >>