Haskell 始めてみる(05)

間があいた。
引数のある場合の data 宣言。
基本的に引数なしと変わらない。

data Point a = Pt a a
pt1 = Pt 3.0 4.9
pt2 = Pt 3.0

相変わらず Pt の定義は気にしない。Point 型の値を作るには、2 行目のように書く。PtPoint 型の値を作るための符牒だと思うべし。
ところで、Pt の型ってなんだろう。そもそも Pt に型なんてあるのか?

 *Main> :t Pt
Pt :: a -> a -> Point a
 *Main> :t pt1
pt1 :: Point Double
 *Main> :t pt2
pt2 :: Double -> Point Double

pt1 は予想通り。Pt の型は、完全に関数の型に見える。データ構築子は関数なのか?
悪ノリしてみる。

f x y = Pt x y
g     = Pt

型は、

 *Main> :t f
f :: a -> a -> Point a
 *Main> :t g
g :: a -> a -> Point a

Ptf、g の型は完全に一致している。Pt は関数といっても文句はなさそう*1

もうすこし色々試す。
型構築子データ構築子が無いとどうなるか。

--data Boo   = x    -- NG
data Boo x = Booo x -- OK

右辺に型構築子データ構築子は必要のようだ。

さらに、右辺のみ or 左辺のみに型変数がある場合。

data Foo x y z = Bar x | Baz y | Pon z	-- OK
data Goo x y z = Dar x | Daz y		-- OK 型変数 z は左辺のみの出現
data Hoo x y z = Par x | Paz y | Kon a	-- NG 右辺に a が突然出てくる

とりあえずまとめ。

  • 全ての型変数は、あらかじめ左辺に出現していないといけない
  • 右辺には、型構築子データ構築子が必須
  • 型構築子データ構築子の型は、関数と同じ。つまり、型構築子データ構築子も一種の関数
    • 型構築子データ構築子は定義が無いが、関数は定義がある
    • 型構築子データ構築子は大文字始まりで、関数は小文字始まり

(追記)

id:hyuki さんに指摘していただいた個所など、訂正、追加を行いました。id:hyuki さん、ありがとうございました。

  • 型構築子とデータ構築子を取り違えていたところを訂正
  • 型変数が左辺のみに現れる data 宣言を追加

*1: コンストラクタは特殊な関数にすぎません。(A Gentle Introduction to Haskell: Functions)