Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Family Polymorphism in Scala

What is the current recommended pattern for family polymorphism in Scala?

While experimenting with ways of modeling games, this solution recently emerged:

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
}

A specific game (Poker in this example) can be expressed in terms of those traits like so:

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 = ...
}

I have several questions about this setup:

  1. How is Game[G <: Game[G]] pronounced in English? What are the names for the roles that G and Game are playing in this situation? (Meaning specifically in this "recursive" relationship.)

  2. Is this a reasonable implementation of "family polymorphism"? At a high level, my understanding is that this means that Game and it's PLAYER and STATE must vary as a "family". The takes on family polymorphism in Scala that I've seen elsewhere differ substantially, and I'm not clear on the different tradeoffs:

    • Scala Overview (2006) http://www.scala-lang.org/docu/files/ScalaOverview.pdf

    • Martin Kneissl blog (2009) http://www.familie-kneissl.org/Members/martin/blog/family-polymorphism-in-scala

  3. Discussion of approaches to family polymorphism involving typeclasses, macros, f-bounded polymorphism, or anything else are welcome.

like image 779
Adam Pingel Avatar asked Jan 03 '13 05:01

Adam Pingel


People also ask

What is Polymorphism in Scala?

Polymorphism is the ability of any data to be processed in more than one form. The word itself indicates the meaning as means many and. means types. Scala implements polymorphism through virtual functions, overloaded functions and overloaded operators.

What types of Polymorphism does Scala support?

Scala has 3 types of Polymorphism that we will explore further below. These are called subtype , parametric and ad-hoc .

What does <: mean in Scala?

It means an abstract type member is defined (inside some context, e.g. a trait or class), so that concrete implementations of that context must define that type.

What is trait in Scala with example?

A Trait is a concept pre-dominantly used in object-oriented programming, which can extend the functionality of a class using a set of methods. Traits are similar in spirit to interfaces in Java programming language. Unlike a class, Scala traits cannot be instantiated and have no arguments or parameters.


1 Answers

I would question the need to define the classes "outside" of the trait at all. The types Player and State are already dependent on Game, so you don't need to try to restrict it further.

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
}

You can use the cake pattern to separate different parts out to different traits/files if you want.

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 = ...
}
like image 137
tixxit Avatar answered Sep 18 '22 16:09

tixxit