Haskell では data Product = Product String Int のようにしてデータ型を定義できる。 これがただの関数だという。 どういうことかわかった(気がする)ので、書き留めておく。
たとえば、商品名と値段を持つ製品データ型というのを考えてみる。
data Product = Product String Int deriving Show
これを使うには:
prd = Product "MacBook Air" 128000
のようにして:
ghci> prd
Product "MacBook Air" 128000
prd の型を調べる:
ghci> :t prd
prd :: Product
では、Product の型シグネチャはどうなっている?
ghci> :t Proudct
Product :: String -> Int -> Product
つまり、String と Int を引数として Product を返す関数なんだ。 だから Product 値を作り出す次のような関数を定義したのと同じになる。
toProduct :: String -> Int -> Product
toProduct name price = Product name price
この toProduct 関数に製品名だけを適用すれば、 (Int -> Product) の型シグネチャを持つ関数が返ってくるはず。
ghci> :t toProduct "MacBook Air"
toProduct "MacBook Air" :: Int -> Product
data で定義した Product の値コンストラクタである Product はただの関数で、toProduct 関数と同じ型シグネチャを持っている。 だから:
ghci> :t Product "MacBook Air"
Product "MacBook Air" :: Int -> Product
toProduct 関数と同じことになる。
たとえば、 MacBook Air 2020 intel と M1 で値段が別だったとして、以下のようなコードが可能になる。
-- 価格だけ未決定の MacBook Air をつくる
macbookAirWithoutPrice = Product "MacBook Air"
-- intel バージョンのそれを価格を入れて完成
macbookAir2020intel = macbookAirWithoutPrice 128000
-- M1 バージョンのそれを価格を入れて完成
macbookAir2020m1 = macbookAirWithoutPrice 98000
GHCi で確認:
ghci> macbookAir2020intel
Product "MacBook Air" 128000
> macbookAir2020m1
Product "MacBook Air" 98000
まあそれだけの話ではあるけど。
データ型で定義した型の値コンストラクタは単なる関数。