Richard Searle

home

Replacing phantom types with implicit evidence

27 Oct 2014

The phantom types can be replaced by implicit evidence as follows

class Door[State <: DoorState] {
  def open(implicit ev: State =:= Closed): Door[Open] = this.asInstanceOf[Door[Open]]
  def close(implicit ev: State =:= Open): Door[Closed] = this.asInstanceOf[Door[Closed]]
}
  
class Room[State <: DoorState](val door: Door[State]) {
  def closeDoor(implicit ev: State =:= Open) = this.asInstanceOf[Room[Open]]
  def openDoor(implicit ev: State =:= Closed) = this.asInstanceOf[Room[Closed]]
}

The style might be considered a little more explicit and perhaps easier to understand. Note that there is additional overhead since instances of the evidence class will be created and passed as arguments.

The fundamental disadvantages remain unchanged.

This blog post describes a more powerful form of the phantom type implementation.

Most phantom type examples are builders, which might perhaps be their only niche.