为什么可以传递不更高种类的类型?
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)
其中 Contravariant
是 companion object of trait Contravariant
,inst
是 type 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"-错误)。
我正在阅读这本书 https://underscore.io/books/scala-with-cats/ 并试图了解 Cats 中的逆变。
在第 68 页上有一个在 Cats
We can summon instances of
Contravariant
using theContravariant.apply
method. Cats provides instances for data types that consume parameters, includingEq
,Show
, andFunction1
. 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)
其中 Contravariant
是 companion object of trait Contravariant
,inst
是 type 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"-错误)。