tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

「ふつうの Haskell プログラミング」一人読書会(1日目)

「ふつうのHaskellプログラミング」という本を読んでいます。

前から Haskell 勉強したいなー、と思っていて、「Real World Haskell」とか、「プログラミングHaskell」とか買ってみて、勉強したのだけど、「なんか説明を端折ってないか?」みたいなところが多々見受けられて、途中から意味分からなくなってしまったので、もう少し簡単そうな本を買ってみました。



ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門

さて、初日は1章と2章の途中まで読んでみました。1章は概略とか Hello World とかなので、問題なく終了。2章からは、Unix コマンドっぽい物体を作っていきます。ソースコードを引用していいのか分からないのと、引用しただけだと何も面白くないので、Perl で書いたソースを使って、どんなことしてるのかを説明していきたいと思います。

最初はおなじみ cat です。ふつうの Perl では

#!/usr/bin/perl
use strict;
use warnings;

while (<>) {
    print $_;
}

こんな感じでしょうか。IO の取り扱い以外は Haskell で書いてもそんなに変わらないようですね。Perl の<>だと、標準入力だけでなく、ファイルも取り扱ってくれるのが長所、Haskell の場合(getContents を使います)は遅延評価なので、一気読みしててもメモリを食いつぶす心配が無いのが長所、といった感じかと思います。*1

次は、countline です。そんなコマンドは無いのですが、まあ wc -l に近いイメージですかね。すなおに Perl で書くとこんなかんじになります。

#!/usr/bin/perl
use strict;
use warnings;

my $lines = 0;
while (<>) {
    $lines++;
}
print "$lines\n";

で、Haskell 風に書くとこんな感じです。

#!/usr/bin/perl
use strict;
use warnings;
print scalar( split(qr/\n/, join ('', <>)) ) . "\n";

変数への代入が無くなり、関数型らしい大変読みやすいコードになりました(棒

感想とか

現時点では、「関数型って結局さっきの countline Haskell風みたいにゴルファーのコードみたいな物体をこさえるだけだよなー、型があるから大丈夫とか嘘くさいなー」と思っています。

Haskell 信者が言うような、「型システムがあるから、型をきちんと考えるのがプログラミングであり、コンパイルが通ればテストは不要」とかそんな話はとても信じられません。*2


素直に書いて、リファクタリングユニットテストもちゃんと書く、ってのが今のところ一番いいプログラミングスタイルであり、言語が変わってもそれは変わらないはずじゃないのかなー、と思っています。

ただ、Perl を含めて最近の言語は関数型っぽい機能がいろいろ追加されてたりするので、関数型を学ぶこと自体は意味があるんじゃないかなー、と思います。

2日目以降もこんな感じで続けられたらな、と思います。

*1:この書き方の場合は Perl の場合もメモリを食いつぶす心配はありません。次に countline の場合のように、配列コンテキストで読むと Perl の場合はメモリを食いつぶす可能性があります

*2:「変数への代入が無いから安全」とか「関数の副作用が無いから安全」とかも同様に信用してません