レコード

レコードは代数的でないデータ型。C の構造体のようなもの。うまい例を思いつかないから,本に載ってるのをそのまま書くとこんな感じ。

 data Point = Pt {x :: Integer, y :: Integer}

x,y をフィールドといい,それぞれ Integer 型の値を取る。具体的に値を定義するにはこうする。

 Pt { x = 1, y = 4 }

代数的データ型を使っても同じようなことはできる。データ構成子が複数の引数を取ることにすればいいし,タプルにしてもいい。これらとレコードが違うのは2点。

  • 名前がついているのでわかりやすい。
  • フィールド名が,同時にフィールドにアクセスするための関数になっている。

2つ目のほうはこんな感じだ。

 *Main> x Pt {x = 2, y = 3}
 2

x という関数が定義されてるってことだな。

 *Main> :t x
 x :: Point -> Integer


さて,じゃあおなじフィールド名を持つレコードを宣言するとどうなるか。

 data TP = Tp { x :: Int, y :: Int } deriving (Eq, Show)
 
 data Point = Pt { x :: Integer, y :: Integer } deriving (Eq, Show)

これを GHCi にロードすると

 Prelude> :l record.hs
 Compiling Main             ( record.hs, interpreted )
 
 record.hs:3:18:
     Multiple declarations of `Main.x'
     Declared at: record.hs:1:15
                  record.hs:3:18
 
 record.hs:3:32:
     Multiple declarations of `Main.y'
     Declared at: record.hs:1:25
                  record.hs:3:32
 Failed, modules loaded: none.

あー,やっぱりだめなわけね。