2017-08-27 87 views
2

我有以下仿函数定义为什么函子更高Kinded型

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,选择,我会问为什么函子必须是更高的亲属类型,并且类型参数F真的意味着什么?

+0

函数是许多(更高kinded)类型如List和Option的通用接口。类型参数F表示“这是我们为接口定义的类型”。 –

+0

Thanks @ n.m。您的解释从代码的角度来看是有意义的。我想问一下为什么仿函数的形式如函数[F [_]]'。在我看来,函子的目标是将F [A]转换为F [B],如果A => B,这里F的含义并不重要。只要F [A]和F [B]有意义,它可以是一个容器或上下文或其他一些容器。 – Tom

+0

如果它不比'map'的签名看起来要高? – sepp2k

回答

2

为什么函子要高kinded型

Functor有更高kinded因为我们要抽象了的类型参数其本身需要一个类型参数。

Functor处理的类型被称为“第一类种类”,其类型为* -> *。当您查看您为Functor提供的实现时,它是有道理的,我们基本上抽象了内部类型参数,例如,当您为List定义仿函数时(如您在示例中所做的那样),将其定义为Functor[List] 。正如你所看到的,我们不是为特定的List[Int]创建一个函子,而是为List中包含的任何类型参数。这种抽象带来巨大的力量,因为一旦你定义了这样一个类型类,你可以用它来为任何List类型,无论是List[String]还是List[Int]

我总是喜欢提到阿德里安·摩尔在他的论文“Genrics的更高层次的”绘制的图像:

Higher Kinds

是什么类型参数F的真正含义是

F的唯一目的是与Functor的实施者定义合同。通过F的签名,我们可以推断出Functor期望的类型。当我们看到它有一个“占位符”([_])时,我们通过约定知道这意味着F应该采用单个类型参数。如果我们想想都觉得需要一个单一的类型参数的类型,我们可以看到,有很多,例如ListOptionTryFutureTask

有关高kinded类型更广泛的解释,见What is a higher kinded type in Scala?

+0

tl; dr:根据定义。 :)当然,如果更高铠应类型已经定义。 – pedrofurla

0

我会回答这个有点不同。在Functor签名中存在(更高版本)类型参数F[_]意味着Functor是一个类型类别。类型类是一种Scala功能,允许在不修改现有类型的情况下添加功能。所以这里不是一个单一的类型,而是许多其他类型的蓝图。换句话说,它不是单一类型,而是一类类型,因此也就是“类型类”这个词。

现在创建一个具体的函子,例如列表的函子,需要将该具体类型作为类型参数传递给该蓝图,如果需要,该具体类型本身必须具有一个类型参数,通过函子的数学定义。这是Functor签名方式中的更高接吻类型F[_]

相关问题