すごいHaskell七章(前半)

 もうこの辺から一筋縄じゃいかなくなる。

データ型の用語

 Boolを例に見る。

data Bool = False | True

 dataキーワードを使って新しいデータ型を定義する。
 等号の前の部分は型の名前。
 等号の後の部分は値コンストラクタ。値コンストラクタはこの型が取り得る値の種類を指定している。
 型名も値コンストラクタも大文字から名前をはじめる必要がある。

フィールドのある値コンストラクタを持つ型を、引数に取る関数のパターンマッチ

 値コンストラクタ名に続けてフィールドも束縛する。

data Shape = Circle Float Float Float |
             Rectangle Float Float FLoat FLoat

 のデータ型に対して、周囲の辺の長さを求める関数を作ってみる。

periphery :: Shape -> Float
periphery (Circle _ r) = pi * r * 2
periphery (Rectangle x1 y1 x2 y2) = (abs $ x2 - x1) * 2 + (abs $ y2 - y1) * 2

 何気に、値コンストラクタの引数のことを「フィールド」と呼ぶのも、ここで出てきた新要素だね。

値コンストラクタは関数

 部分適用でフィールドの一部分が共通の値を作ったり出来る。
 mapが使えるのがすごい。

ghci> map (Rectangle (Point 0 0)) [(Point 5 10), (Point 10 5), (Point 10 10)]
[Rectangle (Point 0.0 0.0) (Point 5.0 10.0),Rectangle (Point 0.0 0.0) (Point 10.0 5.0),
Rectangle (Point 0.0 0.0) (Point 10.0 10.0)]

 こういうのって、単純なように見えて、裏で色々考えられて設計されてるんだと思う。

補助関数っていわゆるFactoryでいいのかな

(前略)ユーザに必要なだけの操作法を提供するが、実装の詳細は隠されているようなデータ型のことを抽象データ型と呼びます。(p.117 訳注)

 メリットは、ライブラリの内部表現を自由に変更できること。ユーザへのインターフェイスを変更しなければ、影響はない。

Main

 プログラミングっぽくなってきた(語弊のある表現)
 まだ全然わかってないんだけど、とりあえずmain関数には main :: IO () の型宣言をするらしい。(コンパイラの警告から)

抽象データ型

ユーザに必要なだけの操作法を提供するが、実装の詳細は隠されているようなデータ型のこと(117p)

 利点は内部表現の実装を後で自由に変更できること。今まで分かってなかった。
 Data.Mapもこの方針をとっている。

レコード構文

 これってJavaで言うところのgetter/setterとかPythonの名前つき引数とかいろいろが綺麗にまとまった形になってる。
 まるで、初めからこれがスタンダードに見えるくらいすっきりしてるし自然だ。