bitterharvest’s diary

A Bitter Harvestは小説の題名。作者は豪州のPeter Yeldham。苦闘の末に勝ちえた偏見からの解放は命との引換になったという悲しい物語

見やすくするならレコード

1.タプルとレコード

複数のデータで一つのデータが構成されるということがよくある。製品と部品、団体とメンバーなどがその例である。タプルは構成要素となっているデータを列挙することで、複合的なデータを表すことができる。しかし、プログラム作成後時間が経つと、それぞれのデータが何を表しているのか思い出すのに時間がかかることが良くある。このような事態の発生を防ぐために用いられるのがレコード構文である。レコード構文はデータベースの記述に良く似ていてフィールドを持つ。フィールドではその名前とその構成要素を与えることができる。

ここでは、簡単な例として、団体名とそのメンバーをレコード構文で表す。まず、シノニムで、団体名IdとメンバーPersonを用意し、データ型Groupを用意し、これが有するフィールド名をname、membersとする。nameはIdをそのタイプとし、membersはPersonのリストをそのタイプとする。また、後で利用するので、Data.Listのモジュールをロードする。プログラムは次のとおりである。

import Data.List

type Id = String
type Person = String
data Group = Group {name :: Id, members :: [Person]}

ここで、二つのグループを用意する。

g1 = Group {name = "Tennis Club", members = ["Tom", "Betty", "Mike", "Bill", "Jenny"]}
g2 = Group {name = "ESS", members = ["Charles", "Carl", "Frank", "Flora", "Bill", "Tom"]}

フィールド名を関数として利用できるので、グループの名前を求めたいときは次のようにする。

name g1
name g2

グループのメンバーを求めたいときは次のようにする。

members g1
members g2

メンバーは集合なので、集合に与えられた関数を用いることができる。例えば、両方のグループに属する人は、積集合intersectを用いて次のように求めることができる。
f:id:bitterharvest:20141014071446p:plain
また、両方を含めて、いずれかのグループに属している人は和集合unionを用いて次のように求めることができる。
f:id:bitterharvest:20141014072212p:plain