类型构造函数参数推断

时间:2020-06-27 13:21:18

标签: scala types scala-cats category-theory type-constructor

我正在经历“ 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[_])中的类型构造函数?据说在几页之前,应该提供type参数来创建类型。这里的整个内容(F[_]是一个类型参数,看起来_是通配符,以便编译器可以推断F的类型参数。

1 个答案:

答案 0 :(得分:3)

类型构造器F[_]必须是Functor类型类的成员。此约束由隐式参数列表施加在F

(implicit functor: Functor[F])

整个签名

def doMath[F[_]](start: F[Int])(implicit functor: Functor[F]): F[Int]

可能解释如下

给出属于F成员的任何类型构造函数Functor 类型类,则doMath可以将类型F[Int]的有效值转换为 类型F[Int]的另一个有效值。

在这里我使用短语有效值来强调它不是原始类型的值,例如Int,而是在应用类型构造函数{{1}之后构造的类型的值}来输入参数F,即Int

此外,我在sense of

中使用短语 member

组建,参加或有关系

请注意,在这种情况下下划线F[Int]的使用与推断无关。 _F[X]类型的构造符表示same的含义。在方法签名的其余部分中,任何地方都不会使用类型参数F[_],因此,根据惯例,我们使用下划线语法X。另一约定是在F[_]中使用小写x,而不是F[x],以强调未使用F[X]

实际上x本身就是一个类型参数,当将类型构造函数F[_]应用到它上时,我们得到的是 proper 类型Functor,即使两个{ {1}}和Functor[F]是类型构造函数,例如

F