为什么可以传递不更高种类的类型?

Why it is possible to pass not higher kinded type?

我正在阅读这本书 https://underscore.io/books/scala-with-cats/ 并试图了解 Cats 中的逆变。
在第 68 页上有一个在 Cats

中实现 Contravariant 的例子

We can summon instances of Contravariant using the Contravariant.apply method. Cats provides instances for data types that consume parameters, including Eq , Show , and Function1 . Here’s an example:

import cats.Contravariant
import cats.Show
import cats.instances.string._

object ContraCats {

  val showString = Show[String]

  val showSymbol = Contravariant[Show]
    .contramap(showString)((sym: Symbol) => s"'${sym.name}'")

  def main(args: Array[String]): Unit = {
    println(showSymbol.show('dave))
  }

}

显示是类型类而不是类型,那么如何创建类型类 Show 的类型类 Contravariant 的实例? Show 不是高等类型。

类型类 Show 声明为 Show[T]

Contravariant 声明为 Contravariant[F[_]]

如果我们这么说

  • Int有种*
  • List[Int]有种*
  • List有种* -> *
  • Monad 声明为 trait Monad[M[_]] 具有种类 (* -> *) -> *

则类推:

  • Show有种* -> *
  • Show[Int]有种*
  • Contravariant有种(* -> *) -> *
  • Contravariant[Show]有种*

也就是说,Contravariant 是一种需要 * -> * 并产生类似 * 的东西。由于 Show 属于 * -> * 类型,因此类型 Contravariant[Show] 有效。

现在,在您的代码片段中,有一个 表达式 Contravariant[Show]。它不是类型,不应与类型构造函数的应用相混淆。脱糖了,这东西本质上是

Contravariant.apply[Show](inst)

其中 Contravariantcompanion object of trait Contravariantinsttype Contravariant[Show] 的隐式提供实例。再一次,一切都无缝地结合在一起。

关于命名法的备注。 我会说 Show 是 "higher kind"。这绝不是确定的,但我喜欢 Atlassian Blog [我的强调和代码缩进] 中的以下引述:

Furthermore, you can have kinds that are themselves parameterized by higher kinded types. So, something could not only take a type, but take something that itself takes type parameters. An example would be the covariant functor: Functor[F[_]], it has the kind:

((* -> *) -> *)

This says: given a simple higher kinded type, produce the final type. For instance given a type constructor like List produce the final type Functor[List].

从上面的引用可以看出,至少 常见List 的种类 * -> * 称为 "higher kind" .绝对高于*。它肯定比你在当前版本的 Java 中能写下的任何东西都要高(如果你在 Java 中写下 List,你能得到的最好结果是一个 "blah blah the generic type List requires type parameters blah blah"-错误)。