Is this a higher kinded type in Scala?

2019-04-27 07:52发布

问题:

Having following definition

type MyMap = Map[String, List[Map[Int, String]]] 

Can Map be defined as a higher kinded type ?

回答1:

It should not.

You can make an analogy with values and functions. You have basic values, which are not functions, such as 5 and "foo". You have then simple functions, which takes simple values as arguments and return simple values, such as + or length. Higher order functions are functions which have other functions as parameters or result. For instance takeWhile, map, or foldLeft are higher order functions.

If you consider types, there are simple types, which are the actual types of values , such as Int, String, or even Int => String and List[Double] (now I consider every values, simple or not, including functions). Then there are parameteric types, which may also be called type constructors (calling them type functions would make the analogy clearer). List (without instanciating the generic parameter) is not really a type for values, you cannot declare a val to be just of type List, it has to be List[Something]. So List may be considered as a function that given a simple type (say Int) returns another simple type (List[Int]). Int, String, and Double and Int => String are said to have kind *, while List has kind * -> *. Parametric types such as List or Map are the analogous of simple functions.

Just as a higher order function is a function with function (instead of simple value) parameter, a Higher order type (or sometimes higher kinded) is a type that has a type constructor parameter, rather than just simple type parameters. It has kind (* -> *) -> *, or something more complex. They are declared with HigherOrder[C[_]], or HigherOrder[C[X]], to tell that the type parameter, C, is itself a parametric type, or type constructor. Note that this has to appear in the type declaration, not the type instantiation. List is declared trait List[A], so it is parametric, but not higher order. If you instanciate one with List[Seq[Map[Int, Set[Double]]], that won't make List's order any higher. A higher order type would accept List (rather than List[Int]) as its parameter, one could declare val x : HigherOrder[List] = ....

Higher order types are not too common in the library, you can spot a few in the gory details of the collection library, such as GenericCompanion. You can find a lot of them in scalaz.



回答2:

What you have is not a higher-kinded type, but it could be quite easily modified to be such.

type MyMap2[A,B,C] = Map[A, List[Map[B, C]]]

Now, we can create MyMap again by providing type parameters.

type MyMap = MyMap2[String, Int, String]

"Higher-kinded" just means that it is a type that is uninhabited, and needs to be provided with other types in order to create an inhabitable type.