2012-06-01 72 views
3

我在試圖製作一個允許用戶將多個處理器鏈接在一起的系統。我遇到的困難是每個處理器實際上都有兩位關心的信息,我希望這些信息以類型安全的方式處理。我煮下來到這個問題:在scala中實例化特徵

考慮:

//First family of stuff 
trait A { 
    def doA {} 
} 

trait B { 
    def doB {} 
} 

//Second family of stuff 
trait X { 
    def doX {} 
} 

trait Y { 
    def doY {} 
} 

我可以在4種口味組合來自兩個家庭的元素結合在一起:

var f = new A with X {} 
f.doA 
d.doX 

var g = new A with Y {} 
//... 

大。問題是我希望每個函數(doA等)都返回這兩種類型的組合,以便我可以將東西鏈接在一起。基本上我想要做的: 性狀A { DEF doThing = { 新與ThingThatImMixedInWithLikeXOrY {}甲 } }

每個處理器需要返回一個匿名類包含:1)已知的處理器2 A型)混入的類型。

我的第一個嘗試是使用仿製藥,是這樣的:

trait A { 
    this : {def makeWithT[TOther]} => 
    def doA = makeWithT[B] 
} 

trait B { 
    this : {def makeWithT[TOther]} => 
    def doB = makeWithT[A] 
} 

trait X { 
    this : {def makeWithS[TOther]} => 
    def doX = makeWithT[Y] 
} 

trait Y { 
    this : {def makeWithS[TOther]} => 
    def doY = makeWithT[Y] 
} 

class Foo[T, S] extends S with T { 
    def makeWithT[OtherT] = new T with OtherT 
    def makeWithS[OtherT] = new S with OtherT 
} 

var f = new Foo[A, X] 
f.doA.doB 
f.doX.doA 
f.doX.doY 
... 

很顯然,我已經運行到一個目錄的問題:

  1. 我不能讓一個泛型類從類型參數延伸

  2. 我不能通過通用參數實例化我的匿名類

  3. 我無法定義特徵中函數的返回類型,因爲我 直到它與某物混合之前才知道該類型。

我有點小白,當談到Scala和我得到的,我在完全錯誤的方式去了解這個感覺,也許我應該使用implicits和CanBuildFrom模式。任何幫助將不勝感激。

乾杯

+2

您最大限度地減少了問題並使其非常抽象。在某些情況下,這可能是一件好事,但我認爲在這種特殊情況下,如果您會向我們描述具體問題和您想要存檔的目標,那將會更有幫助。據我所知,在這個問題中,你正在描述我們還不知道的問題的(破解)解決方案。如果你願意與我們分享,可能我們會爲你目前面臨的問題提出另一個/更好的/有效的解決方案...... – tenshi

+0

好的,這裏有。我想要一個語法,以便我可以執行諸如 dataSource.map(...)。filter(...) 其中dataSource是我自己的一種流。問題是,我想對其執行其他操作,而不是轉換,而是修改計算的執行方式。 例如,我可能想要做datasource.asParallel.filter(...)。asSequential。 這是一個稍微做作的例子,但你可以看到我有兩組操作。 asParallel的返回類型需要是暴露asSequential操作的東西。 –

回答

1

爲可堆疊的處理器的最公知的解決方案是可堆疊性狀

http://www.artima.com/scalazine/articles/stackable_trait_pattern.html

trait StackableRoot { 
    def StackablePass (x:Int) : x 
} 
trait StackableDouble extends StackableRoot { 
    def internalPass (x:Int) = 2*x 
    abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x)) 
} 
trait StackableIncrement extends StackableRoot { 
    def internalPass (x:Int) = x+1 
    abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x)) 
} 

有一些樣板與

abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x)) 

不能被避免因爲它將要求包裝成參數化的特徵e scala繼承了多次不同參數的特徵,這是被着名類型擦除禁止的多次

相關問題