人気ブログランキング | 話題のタグを見る

RWH の読み方(10) 第2章

Real World Haskell の第2章 Types and Functions のまとめの最終回。

The Type of a Function of More Than One Argument

引き数が2つ以上の関数の型 (type signature) がどのように表記されるかという説明。

Prelude> :type take
take :: Int -> [a] -> [a]

上の関数の型をみると、関数 take の引き数が Int と [a] (リスト) で結果が [a] リストになるというのは分かるが、それが全部 -> でつながれている。なぜ Int, [a] -> [a] にしないのかという疑問が湧くがこれは次のように解釈する必要がある。

take :: Int -> ([a] -> [a])

つまり、take は Int という一個の引き数をとり、([a] -> [a]) 型の関数を戻値として戻す関数であるという見方だ。この意味は関数の部分適用とカリー化に関係するが後述すると書いてある。

Haskell は関数を値として考えることができるのでこのような芸当ができる。関数を全て1引き数の関数と考えるやりかたは IO モナドの >= 演算子を活用する際に重要になってくる。

Why the Fuss over Purity?

なぜ、関数の純粋性 purity が必要なのかという説明。最初に not の関数の型を表示してそれから何が考えられるのかということを推測している。

Prelude> :type not
not :: Bool -> Bool

この関数の型をみれば、not がどういう動作をするのか知らなくても、結果が引き数を無視していつもTrueかFalseを返すとか、引き数の値をそのまま戻すとか、引き数の値を反転して戻すとか推測できる。

それと同時に、この関数がファイルにアクセスしたり、ネットワークに接続したり、時刻を取得したりできないのが分かる。つまり、not は副作用をもたず、純粋関数であるということだ。

純粋関数の結果はグローバル変数の値や、データベースのデータやネットワークの接続の状況に影響されない。純粋な関数は本質的に modular (モジュール化されている)で、自己完結 self-contained していて、明確なインターフェース well-defined interface を持っている。

Haskell の関数は純粋関数が標準なので、そのコードは入力によってのみ結果が戻され、入力以外の影響で結果が変化することはない。

(副作用というとその関数の実行が他の関数に影響するという意味に捉えやすいが、上の説明をみると、目に見えない他の状況が関数の結果に影響すると考えるほうが、その影響を理解しやすいような気がする。純粋関数が同じ入力にたいしいつも同じ出力を返すというのは、目に見えないグローバルな環境の影響を全く受けないということだ -- 管理人)

副作用のある関数と、純粋関数をはっきりと分けることは、目に見えない攻撃からコードを守ることになる。

まとめ

これで Real World Haskell の第2章まで読み終えたことになる。第1章、第2章と読んできて、この本が Haskell についてどのように解説しようとしているのかが分かる。それは、具体的な Haskell の使い方を超えて、Haskell というプログラム言語のもつ思想を伝えたいと考えているようだ。そうして Haskell の設計思想の根底にあるものが、型システムと抽象性だ。

管理人が RWH を何回読んでも忘れてしまっていたのは、How to ではなく、What is が書かれていたためだろう。これは知っていると流し読みした箇所に書かれていた、Haskell とは何かという意味を読み取ることが出来なかったからだ。

RWHに具体例が記載されていないわけではなく、3章以下は実際に動くプログラムを作りながら Haskell の特徴を理解していくような記述がされている。読者はそれらの例を実際にファイルに作成して動作を確認しながら読み進めたほうがいいだろう。ただ、その際も Haskell とは何かという著者のメッセージを逃さないように読んでいったほうがいいのかもしれない。

このままプログで3章以下を続けることも考えたが、それは、日本語訳の本も出版されているので重複するのではないかと考えたので2章まででやめることにする。正直、人に伝えるために書くのはしんどい。実際、3章以下は読めていなかったので、管理人自身がこれから読むことになる。

Haskell は奥が深いようだ、3章以下を読むのが楽しみだ。
by tnomura9 | 2012-02-22 07:44 | Haskell | Comments(0)
<< Haskell 記事リスト R... RWH の読み方(9) 第2章 >>