現在Scalaに入門中なのですが、「高カインド型」(Higher kinded types)という用語の意味がよく分からなかったので調べてみました。
参考資料
独習 Scalaz — 型を司るもの、カインド
Iterator パターンの本質 | eed3si9n
カインド (型理論) - Wikipedia
Scala: Types of a higher kind | Atlassian Blogs
用語の前提
- 型とカインド
型 - 値に付いているラベルのこと。(Int, String、List[Int]等)
カインド - 基本型もしくは型コンストラクタ(後述)に付いているラベルのこと。(A, F[A]等)
注)
上記の「A」のように、型パラメータを必要としない型を「プロパー型」「基本型」もしくは「データ型」という。
Aは「*」、F[A]は「* -> *」のようにして表す記法もある。(むしろその記法の方が正式かもしれない)
注)
基本型のことを、「0個の型パラメータをとる」と見なして「零項(0階)の型コンストラクタ」とする場合もあるらしい。
- 関数と型コンストラクタ
値コンストラクタ - 値を引数にとって値を返すなにか。要するに関数のこと。
型コンストラクタ - 型を引数にとって型を返すなにか。
- 一階と高階
一階関数 - 値を引数にとる関数のこと。
高階関数 - 関数を引数にとる関数のこと。
結論
「高カインド型」とは、要するに「高階の型コンストラクタ」のことで、高階関数が
「関数を引数にとる関数である」のと同様に、
「型コンストラクタを型パラメータにとる型コンストラクタである」と考えてよいと思われます。
下記のように、関数と照らし合わせて覚えると頭に入りやすいのではないでしょうか。
階数 | 関数 | 型コンストラクタ |
---|---|---|
一階 | 値 -> 値 | 型 -> 型 |
高階 | 関数 -> 値 | 型コンストラクタ -> 型 |
カインドの用途
関数やクラスの引数の「型」がコンパイル時にチェックされるのと同様に、関数やクラスの「型パラメータ」のチェックをコンパイル時に行う用途で使用されているものと思われます。
要するにGenerics系の機能を持っている言語なら多分必ず備えている機能なのかなと。
(ただしこちらの資料を見る限りでは、「高カインド型」の機能を持っている言語はScalaやHaskell等ごく一部のようですが)
具体例
(:kind
(省略形は:k
)は、型のカインドを表示するコマンドです)
scala> class MyClass0
scala> class MyClass1[A] {}
scala> class MyClass2[A[_]] {}
scala> class MyClass3[A[B[_]]] {}
scala> class MyClass4[A[B[C[_]]]] {}
scala> :k -v MyClass0
MyClass0's kind is A
*
This is a proper type.
scala> :k -v MyClass1[Int]
MyClass1's kind is F[A]
* -> *
This is a type constructor: a 1st-order-kinded type.
scala> :k -v MyClass2[MyClass1]
MyClass2's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.
scala> :k -v MyClass3[MyClass2]
MyClass3's kind is Y[X[F[A]]]
((* -> *) -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.
scala> :k -v MyClass4[MyClass3]
MyClass4's kind is Z[Y[X[F[A]]]]
(((* -> *) -> *) -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.
- MyClass0 零階の型コンストラクタ(プロパー型)
- MyClass1 一階の型コンストラクタ
- MyClass2 二階の型コンストラクタ
- MyClass3 三階の型コンストラクタ
- MyClass4 四階の型コンストラクタ
まとめ
カインドに関しては、「Higher kinded types」とか「higher-order types」とか「Higher kind Generics」とかtype constructor parameter」とか色々な用語が使用されているのが、初心者にとっての分かりにくさの一つの原因だと思うので、用語を統一してほしいとこですね(-_-;)