2013-01-03 18 views
9

Scala'da aile polimorfizmi için şu anki önerilen model nedir? Scala'da Aile Polimorfizmi

modelleme oyunların yolları deneme ederken, bu çözüm son zamanlarda ortaya çıkan:

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 
} 

spesifik bir oyun (bu örnekte Poker) şöyle bu özelliklerin cinsinden ifade edilebilir:

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. Nasılgeçerli:

    Bu kurulumu hakkında birkaç soru var 0, İngilizce 'de bildirilmiştir? G ve Game'un bu durumda oynadığı rollerin adları nelerdir? (Bu "özyinelemeli" ilişkide özellikle anlamlıdır.)

  2. Bu "aile polimorfizminin" makul bir uygulaması mı? Üst düzeyde, benim anlayışım bunun Oyun ve OYUNCU ve DEVLET'in bir "aile" olarak değişmesi gerektiği anlamına geliyor. 2009 (

  3. Tartışma açıktır.

+0

Suereth'in "Derinlikteki Scala" listelemesinin 7.6'sında, benzer kısıtlamaları olan daha yüksek bir "FileLike" özelliği gösterilir. Bu listeleme, Typeclasses'ın daha iyi neler yapabileceğinin bir örneği olarak kullanılır. [Typeclass alternatifi değiştirdiği versiyondan çok daha sezgisel görünüyor, bu yüzden temel bir şeyi kaçırdığımı farz ediyorum.] –

cevap

2

Özelliklerin "dışında" sınıflarını tanımlama gereğini sorgulayacağım. Player ve State türleri zaten Oyuna bağımlıdır, dolayısıyla daha fazla kısıtlamaya çalışmanıza gerek yoktur.

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 
} 

İsterseniz farklı parçaları farklı özelliklere/dış dosyalara ayırmak için kek desenini kullanabilirsiniz.

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

Teşekkürler! Evet, bu daha çok deyimsel görünüyor. Soruyu sorduğumdan beri bir süre geçti, bu yüzden kısa bir süre önce kodu ve çözümünüzü yeniden tanıtacağım. –