2013-11-05 113 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