すごい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もこの方針をとっている。