2013-01-03 33 views
9

目前推薦的Scala中的家族多態性模式是什麼?Scala中的家族多態性

雖然與模擬遊戲的方式進行試驗,該解決方案最近出現了:

trait Game[G <: Game[G]] { 

    type PLAYER <: Player[G] 
    type STATE <: State[G] 

    def players(): Set[G#PLAYER] 

    def startState(): G#STATE 
} 

trait Player[G <: Game[G]] 

trait State[G <: Game[G]] { 
    def player(): G#PLAYER 
} 

特定遊戲(撲克在這個例子中)可以在這些特質來表示,像這樣:

class Poker() extends Game[Poker] { 

    type PLAYER = PokerPlayer 
    type STATE = PokerState 

    val p1 = new PokerPlayer() 

    def players() = Set(p1) 

    def startState(): PokerState = ... 
} 

class PokerPlayer() extends Player[Poker] 

class PokerState() extends State[Poker] { 
    def player(): PokerPlayer = ... 
} 

我對這個設置幾個問題:

  1. 如何爲Game[G <: Game[G]]在英語中的發音GGame在這種情況下扮演角色的名字是什麼? (具體意義在這種「遞歸」關係中。)

  2. 這是「家族多態性」的合理實現嗎?在很高的層面上,我的理解是,這意味着遊戲和它的玩家和國家必須作爲一個「家庭」而變化。該呈現在斯卡拉家族多態性,我已經在其他地方看到很大的不同,我並不清楚對不同的權衡:

  3. 討論涉及的類型類,宏,F-界多態性,或其他任何方法來家庭多態性的歡迎。

+0

在Suereth的「Scala深度」的代碼清單7.6中,顯示了一個具有類似約束的較高主觀'FileLike'特徵。該列表被用作Typeclasses可以做得更好的一個例子。 [Typeclass的替代方案似乎比它替換的版本更直觀,所以我認爲我錯過了一些基本的東西。] –

回答

2

我會質疑是否需要定義特性「外部」的類。 PlayerState類型已經依賴於遊戲,因此您不需要進一步限制它。

trait Game { 
    type Player 
    type State <: StateLike 

    trait StateLike { 
    def player: Player 
    } 

    def startState: State 
} 

class Poker extends Game { 
    class Player 
    class State extends StateLike { ... } 
    val startState = new State 
} 

如果需要,您可以使用蛋糕模式將不同的部分分開到不同的特徵/文件中。

trait PokerPlayer extends Game { 
    class Player 
} 
trait PokerState extends Game with PokerPlayer { 
    class State extends StateLike { ... } 
} 
class Poker extends Game with PokerPlayer with PokerState { 
    val startState = ... 
} 
+0

謝謝!是的,這看起來更加習慣。我提出這個問題已經有一段時間了,所以我很快就會重新熟悉代碼和解決方案。 –