我有以下仿函数定义
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object ListFunctor extends Functor[List] { //
def map[A, B](f: A => B)(data: List[A]): List[B] = data map f
}
在scala中,F
是一个集合类型很常见,例如List,Seq,Option,我会问为什么Functor必须是更高的kinded类型,以及类型参数{{1真的是吗?
答案 0 :(得分:6)
为什么Functor必须是更高级的kinded类型
Functor
必须更高一些,因为我们希望抽象一个类型参数,它本身采用一个类型参数(我们称之为类型构造函数,认为Functor[List]
是一个具体的例子)。
Functor
处理的类型类型称为"第一顺序种类",其类型为* -> *
。当您查看Functor
的具体实例时,您会看到我们不提供内部类型参数。例如,当您为示例中的List
定义仿函数时,将其定义为Functor[List]
。我们不是为正确类型(即List[Int]
)创建仿函数,而是为List
中包含的任何类型创建仿函数。这种抽象带来了巨大的力量,因为你可以将它用于任何适当的List
类型(种类*),无论是List[String]
,List[Int]
等。
我总是喜欢参考Adriaan Moore在他的论文中绘制的图像"更高级的种类":
类型参数F的真正含义是什么
F
的唯一目的是与Functor
的实施者定义合同。通过F
的签名,我们可以推断出Functor
所期望的类型。当我们看到它有一个"占位符" ([_]
)按惯例,我们知道这意味着F
应该采用单一类型参数。如果我们考虑采用单个类型参数的所有类型,我们可以看到有很多类型,例如List
,Option
,Try
,Future
,{{ 1}}等等。
有关更高级别的类型的更广泛说明,请参阅What is a higher kinded type in Scala?
答案 1 :(得分:-1)
我的回答有点不同。 F[_]
签名中{(1}}签名意味着Functor
中存在(较高通道)类型参数Functor
是类型类。 Typeclasses是一种Scala功能,允许用户在不修改现有类型的情况下添加功能。所以Functor[F[_]]
这里不是单一类型,而是许多其他类型的蓝图。或者,换句话说,它不是单一类型,而是一类类型,因此单词"类型类型"。
现在创建一个具体的仿函数,例如列表的仿函数,需要将该具体类型作为类型参数传递给该蓝图,如果您愿意,该具体类型本身必须具有一个类型参数,通过仿函数的数学定义。这就是F[_]
签名中高等级Functor
类型的含义。