主要编辑以更好地反映我的意图:
// this *must* be outside of Team
class Player
class Team(val p1: Player, val p2: Player) {
type P = ??? // <-- what to put here ? see below ...
// perhaps I can somehow construct a union type:
// type P = p1.type union p2.type
// or perhaps the following :
// type P = Either[p1.type,p2.type]
// The purpose of `P` here is to define a type which can only hold p1 or p2 for values.
def position(p: P) = p match {
case `p1` => 1
case `p2` => 2
// Gotcha ! we never get here (=exactly what I want to enforce) if I can get the `P` right !
}
}
val p1=new Player
val p2=new Player
val someP = new Player
val t= new Team(p1,p2)
t.position(t.p1) // allowed
t.position(t.p2) // allowed
t.position(p1) // allowed, since p1 is the same thing as t.p1, or is it ?!
t.position(p2) // allowed, since p2 is the same thing as t.p2, or is it ?!
t.position(someP) // I want this to *not* type-check : Required t.P, Found Player
原始片段在这里:
// this *must* be outside of Team
class Player
class Team(p1: Player, p2: Player) {
def position(p: Player) = p match {
case `p1` => 1
case `p2` => 2
// Ah-oh !! is it possible to prevent this using (probably path-dependent) types ?
}
}
val p1=new Player
val p2=new Player
val someP = new Player
val t= new Team(p1,p2)
t.position(p1) // allowed
t.position(p2) // allowed
t.position(someP) // I want this to *not* type-check with an error like "Required: t.Player, Found: Player"
答案 0 :(得分:1)
这可能有点矫枉过正,但它解决了你的问题
class Team(p1: Player, p2: Player) {
case class Membership(player: Player)
def position(m: Membership) = m.player match {
case `p1` => 1
case `p2` => 2
// Ah-oh !! is it possible to prevent this using (probably path-dependent) types ?
}
}
class Player
val p1 = new Player
val p2 = new Player
val someP = new Player
val t = new Team(p1, p2)
val someT = new Team(someP, someP)
val m1 = t.Membership(p1)
val m2 = t.Membership(p2)
val someM = someT.Membership(someP)
t.position(m1) // allowed
t.position(m2) // allowed
t.position(someM) // This doesn't compile
//type mismatch; found : Test.someT.Membership required: Test.t.Membership