函数式编程 - Type Class 介绍

2019-03-12 16:07:17 浏览数 (2)

什么是 Type Class ?

Type Class (类型类) 的概念来自 Haskell,表示一系列函数的集合,在概念上, Type Class 和面向对象领域的泛型接口比较类似。

由于 Haskell 是一门纯函数式编程语言,没有类和接口的概念,所以使用 Type Class 表达类似接口的概念。例如 Haskell 的 Ord 类型类在概念上和 Java 的 Comparable 非常类似。

在 Haskell 中,Type Class 使用 class 关键字定义:

代码语言:javascript复制
class BasicEq a where
    isEqual :: a -> a -> Bool
    isEqual x y = not (isNotEqual x y)

    isNotEqual :: a -> a -> Bool
    isNotEqual x y = not (isEqual x y)

Type Class Instance 则使用 instance 关键字定义:

代码语言:javascript复制
instance BasicEq Bool where
    isEqual False False = True
    isEqual True  True  = True
    isEqual _     _     = False

只要定义了 Bool 类型的 Type Class Instance,我们就可以在任何地方使用 isEqual 方法比较 Bool 类型的相等性。用面向对象的语言描述就是:Bool 类型实现了 BasicEq 接口。

Type Class 的好处是,当系统增加一个新类型时,只需要实现该新类型的 Type Class Instance 即可,已有类型代码可以保持不变。

Java中的 Type Class

在面向对象领域使用接口解决类似 Type Class 的问题,例如 Java 的 Comparable 接口。但是接口的方式并不优雅,它要求新类型必须实现 Comparable 接口,如果这个新类型来自第三方库,我们无法强制要求它实现 Comparable 接口。所以在面向对象领域,我们仍然可以借鉴 Type Class 的方式以解决接口所面临的问题。所以 Java 提供了一个 Type Class 的等价物,即 Comparator<T>接口,所有实现了Comparator<T>接口的实例即为 Type Class Instance。针对一个新类型Person,我们只需要实现一个Comparator<Person>实例,即可以在任何地方对Person集合进行排序。

Scala 中的 Type Class

同样的,Scala 的核心库设计中也采用了 Type Class 的概念。例如Ordering[T] 是一个 Type Class, IntOrdering 是一个 Type Class Instance。所以只要有IntOrdering实例,我们就可以对Int类型进行排序:

代码语言:javascript复制
def sorted[B >: A](implicit ord : scala.math.Ordering[B])

由于Ordering中已经预定了常见的Type Class Instance 的隐式对象,所以我们可以在任何地方对常见类型进行排序。

0 人点赞