case class NetworkSwitch(name: String) { thisSwitch =>
case class Port(nr: Int) {
val switch = thisSwitch
}
def switchPortOn(port: Port): Unit = { println(s"Switching on $port") }
}
def switchOffAnyPort(port: NetworkSwitch#Port): Unit =
println(s"switching off $port on ${port.switch}")
Using this:
scala> val switch1 = new NetworkSwitch("sw1")
scala> val switch2 = new NetworkSwitch("sw2")
scala> val port1 = switch1.Port(12)
scala> val port2 = switch2.Port(25)
scala> switchOffAnyPort(port1)
switching off Port(12) on NetworkSwitch(sw1)
scala> switchOffAnyPort(port2)
switching off Port(25) on NetworkSwitch(sw2)
scala> switch1.switchPortOn(port1) // OK: switch-on a port on a switch to which the port "belongs"
Switching on Port(12)
scala> switch1.switchPortOn(port2) // Not OK: mix-up port& switch - demonstrates the usefulness of Path Dependent Types
^
error: type mismatch;
found : switch2.Port
required: switch1.Port