类型构造函数参数推断
Type constructor parameter inference
我正在学习“Scala with cats”。在 3.5.2(第 58 页,底部)中有一个示例:
def doMath[F[_]](start: F[Int])(implicit functor: Functor[F]): F[Int] =
start.map(n => n + 1 * 2)
而且用法非常简单:
import cats.instances.option._ // for Functor
import cats.instances.list._
// for Functor
doMath(Option(20))
// res3: Option[Int] = Some(22)
doMath(List(1, 2, 3))
// res4: List[Int] = List(3, 4, 5)
如何理解方法签名中的类型构造函数(F[_]
)?前面几页曾说过,应该提供类型参数来创建类型。这里整个东西 (F[_]
) 是一个类型参数,看起来 _
是一个通配符,因此编译器可以推断出 F
.
的类型参数
类型构造函数 F[_]
必须是 Functor
类型类的成员。此约束由隐式参数列表
放在 F
上
(implicit functor: Functor[F])
整个签名
def doMath[F[_]](start: F[Int])(implicit functor: Functor[F]): F[Int]
可能解读如下
Given any type constructor F
that is a member of Functor
typeclass, then doMath
can transform effectful value of type F[Int]
to
another effectful value of type F[Int]
.
我在这里使用短语有效值来强调它不是原始类型的值,例如Int
,而是应用类型后构造的类型值构造函数 F
键入参数 Int
,即 F[Int]
.
此外,我在 sense of
中使用短语 的成员
forms a, or participates in, or has a relationship
请注意,在此上下文中使用下划线 _
与推理无关。 F[X]
和 F[_]
类型构造函数符号的意思正是 的意思。方法签名的其余部分没有使用类型参数 X
,因此按照惯例我们使用下划线语法 F[_]
。另一个约定是在F[x]
中使用小写的x
,而不是F[X]
,以强调x
不被使用。
确实 F[_]
本身就是一个类型参数,当类型构造函数 Functor
应用于它时,我们得到 proper 类型 Functor[F]
尽管 F
和 Functor
都是类型构造函数,例如
scala> :kind -v List
List's kind is F[+A]
* -(+)-> *
This is a type constructor: a 1st-order-kinded type.
scala> :kind -v cats.Functor
cats.Functor's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.
scala> :kind -v cats.Functor[List]
cats.Functor[List]'s kind is A
*
This is a proper type.
我正在学习“Scala with cats”。在 3.5.2(第 58 页,底部)中有一个示例:
def doMath[F[_]](start: F[Int])(implicit functor: Functor[F]): F[Int] =
start.map(n => n + 1 * 2)
而且用法非常简单:
import cats.instances.option._ // for Functor
import cats.instances.list._
// for Functor
doMath(Option(20))
// res3: Option[Int] = Some(22)
doMath(List(1, 2, 3))
// res4: List[Int] = List(3, 4, 5)
如何理解方法签名中的类型构造函数(F[_]
)?前面几页曾说过,应该提供类型参数来创建类型。这里整个东西 (F[_]
) 是一个类型参数,看起来 _
是一个通配符,因此编译器可以推断出 F
.
类型构造函数 F[_]
必须是 Functor
类型类的成员。此约束由隐式参数列表
F
上
(implicit functor: Functor[F])
整个签名
def doMath[F[_]](start: F[Int])(implicit functor: Functor[F]): F[Int]
可能解读如下
Given any type constructor
F
that is a member ofFunctor
typeclass, thendoMath
can transform effectful value of typeF[Int]
to another effectful value of typeF[Int]
.
我在这里使用短语有效值来强调它不是原始类型的值,例如Int
,而是应用类型后构造的类型值构造函数 F
键入参数 Int
,即 F[Int]
.
此外,我在 sense of
中使用短语 的成员forms a, or participates in, or has a relationship
请注意,在此上下文中使用下划线 _
与推理无关。 F[X]
和 F[_]
类型构造函数符号的意思正是 X
,因此按照惯例我们使用下划线语法 F[_]
。另一个约定是在F[x]
中使用小写的x
,而不是F[X]
,以强调x
不被使用。
确实 F[_]
本身就是一个类型参数,当类型构造函数 Functor
应用于它时,我们得到 proper 类型 Functor[F]
尽管 F
和 Functor
都是类型构造函数,例如
scala> :kind -v List
List's kind is F[+A]
* -(+)-> *
This is a type constructor: a 1st-order-kinded type.
scala> :kind -v cats.Functor
cats.Functor's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.
scala> :kind -v cats.Functor[List]
cats.Functor[List]'s kind is A
*
This is a proper type.