学習の素材は、
すごいHaskellたのしく学ぼう!
この表記は、私見・感想です。
以前に投稿した、型コンストラクタの意味に対する、別教材からの自己解決記事にもなっています。
型コンストラクタと関数との類似点
次の点で、型コンストラクタと関数では類似点がある。
- 部分適用ができる
- いずれは具体型になる(関数が値を引数にとって値を生み出すように)
だから、関数の引数としてある関数を加工(部分適用)するように、型クラスのインスタンスの型引数として、ある型を加工(部分適用)することができる。
型の種類とは
型とは、値について何らかの推論をするために付いているラベルのようなもの。また型にもラベルが付いている。このラベルのことを種類( kind )と呼ぶ。
用語 | 意味 | 例 |
---|---|---|
* |
具体型を表す記号。型引数をとらない型のこと。値に付けられる型は、* つまり具体型だけである。 |
Int |
* -> * |
一つの具体型をとって具体型を返す型コンストラクタ | Maybe |
* -> * -> * |
二つの具体型をとって具体型を返す型コンストラクタ | Either |
例えば isUpper
は Char -> Bool
型であり、isUpper 'A'
はBool
型である。どちらも具体型なので、型の種類( kind )は *
となる。
値の型 と 型の種類 とは、捉え方に違いがあることに注意する。型の種類は、多相型なのか(そして型引数はいくつか)、具体型なのか、がポイント。ちなみに、値の型はすべて具体型でなくてはならない。
型コンストラクタも(関数と同様に)カリー化されているので、部分適用できる。
Prelude Data.Char> :k Either
Either :: * -> * -> *
Prelude Data.Char> :k Either Int
Either Int :: * -> *
Prelude Data.Char> :k Either Int String
Either Int String :: *
他の例として、 Functor クラスを見てみると、この型クラスのインスタンスになるためには、* -> *
の種類の型コンストラクタでなくてはならないことがわかる。
class Functor f where
fmap :: (a -> b) -> f a -> f b
ここで、 f a
は関数の型宣言にて値の型として使われていることから具体型でなくてはならない。つまり、f
は型引数を一つとることで具体型となる型コンストラクタであることが導ける。