Scala中的ADT子类型

est*_*lua 5 generics scala algebraic-data-types

是否有与Scala中使用的ADT模式的子类型的OO概念等效?特别是我想将方法​​添加到更专业的类型.例如,给定一个通用的List ADT:

sealed trait List[+A]
case class Cons[+A](h: A, t: List[A]) extends List[A]
case object Nil[Nothing]
Run Code Online (Sandbox Code Playgroud)

我想为特定类型的列表定义新方法:

sealed trait List[+A]
sealed trait DuckList extends List[Duck] {
    def feed(l: DuckList) = ...
}
Run Code Online (Sandbox Code Playgroud)

但是我还必须为这些新类型定义特殊的数据构造函数(DuckCons,DuckNil),并且由于case类不支持(case-to-case)继承,所以没有办法将DuckCons与泛型相关联这样可以在模式匹配中工作,因此为List定义的泛型方法不适用于DuckList.

Dan*_*ral 10

使用类型类模式.

举一个例子,考虑如何Ordering实现.它compare为一组封闭类添加了一个方法 - 但它不是直接添加方法,而是提供一个具有该特定类的方法的实例.Ordering[Int],继续这个例子,实现如下:

trait IntOrdering extends Ordering[Int] {
  def compare(x: Int, y: Int) =
    if (x < y) -1
    else if (x == y) 0
    else 1
}
implicit object Int extends IntOrdering
Run Code Online (Sandbox Code Playgroud)

也就是说,对象Ordering.Int(对象内部Ordering)实现了一个compare以两个Int为参数的方法.隐式提供此对象,因此用户无需显式传递它.Listsorted方法利用了这个:

def sorted[B >: A](implicit ord: math.Ordering[B]): List[A]
Run Code Online (Sandbox Code Playgroud)

然后它可以调用ord.compare列表的实例来对它们进行排序.我鼓励你去Ordering了解它在做什么.