2013-11-05 112 views
5

是否有与Scala中使用的ADT模式的子类型相关的OO概念? 特别是我想将方法​​添加到更专业的类型。例如,给定一个泛型列表ADT:Scala中的ADT子类型

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

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

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

但我也不得不定义特殊数据构造( DuckCons,DuckNil),因为case类不支持(case-to-case)继承,所以没有办法将DuckCons与泛型Cons相关联,这样它就可以在模式匹配中工作,所以泛型为列表定义的方法不适用于DuckList。

回答

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 

也就是说,对象Ordering.Int(因为这是对象Ordering内)实现的方法compare采用两个Int作为参数。这个对象是隐式提供的,所以用户不需要明确地传递它。 Listsorted方法利用了这一点:

def sorted[B >: A](implicit ord: math.Ordering[B]): List[A] 

然后,它可以调用ord.compare在列表的情况下,对它们进行排序。我鼓励你看看Ordering以了解它在做什么。 “

+0

”此转换是隐式提供的,因此用户不需要明确传递它。“什么转换?有一个简单的隐含参数,对吧?没有转换AFAIK。 – Felix

+0

@Felix对,我错过了。 –

+0

所以这个解决方案允许扩展定义(先前定义的)泛型方法的类型特定行为,但它实际上并不允许新方法的定义正确吗?所以我只能在我的示例中实现'feed'方法,如果它已经在'List'中可用,至少作为一个抽象方法。 – estolua