型と型クラス

9.2 代数的データ型


う〜ん、なかなか難しい用語ですね。
見失わないように頑張ります。

型コンストラクタとデータコンストラクタについて

本文中の例に習うと、

data FontTag = Font Int String String


でHTMLのFONTタグを表してみました。
この中のFontTagが型コンストラクタ。この型コンストラクタが型名。
う〜ん、型名=型コンストラクタ?
なんかちょっと違う概念のような。たとえばC++などでは、

class FontTag {
    private int size;
    private string color;
    private string str;

    // ...
};

// ...

FontTag font = new FontTag(...);


と書く。
確かに型名がそのままコンストラクタ名になってるけど、
Haskellで言うところの型コンストラクタはこの例のコンストラクタとは違う。
この例で言うところのコンストラクタはデータコンストラクタに当たるようだ。
FontTagでいうと、Fontがデータコンストラクタに当たる。
実際FontTag型の値を作成するには

tag = Font 12 "green" "hogehoge"

などと書く(合ってるかな?)。型名とコンストラクタ名を分けて書くんですね。
逆にいうと、型名とコンストラクタ名を同じに出来るのかな?
ちょっと試してみる。

main = do print $ getsize tagtag
          print $ getcolor tagtag
          print $ getstr tagtag

{--
  型コンストラクタとデータコンストラクタの
  名前を同じにするとどうなる?
--}
data Font = Font {aSize  :: Int,
                  aColor :: String,
                  aStr   :: String}

{--
  フィールドラベルのパターンマッチでフィールドへのアクセス
--}
tagtag :: Font
tagtag = Font 14 "red" "This is font tag."

getsize :: Font -> Int
getsize (Font {aSize = size}) = size

getcolor :: Font -> String
getcolor (Font {aColor = color}) = color

getstr :: Font -> String
getstr (Font {aStr = str}) = str


問題ないみたい。ついでにフィールドラベルのアクセスもやってみました。
と思い次の節を除いてみると…こんな面倒くさいことしなくても、各メンバにアクセス出来るんだ。。。