假设我有以下内容:
class Deck[+T] {
class Card(value: T)
class Pile(val cards: List[Card]) {
val deck = Deck.this
def shuffle(shuffler: Shuffler): shuffler.shuffle(this)
}
}
trait Shuffler {
def shuffle[T](pile: Deck[T]#Pile): pile.type
}
object Shuffler {
def randomShuffler(r: Random): Shuffler = new Shuffler {
override def shuffle[T](pile: Deck[T]#Pile): pile.deck.Pile = {
new pile.deck.Pile(r.shuffle(pile.cards))
}
}
}
如果在
val deck
中没有Pile
声明,是否可以做同样的事情?另外,如果没有T
中的shuffle()
声明,是否可以做同样的事情?我一直在玩诸如
pile: x.Pile forSome {val x: Deck[_]}
之类的东西,但是由于键入问题它们似乎无法编译(阅读:我没有完全理解其中的语义),并且我试图避免将Shuffler
重写为,而是使用原始列表(无论如何我要表达出来吗?List[Deck[T]#Card]
并不在那里,因为我想要来自同一Card
的Deck
列表)。 最佳答案
如果在val deck
中没有Pile
声明,是否可以做同样的事情?
如果我们要强制执行一个您似乎想要的值依赖类型,则不是(例如,两个Pile[Int]
仅在引用相同的存储卡值的情况下才兼容)。
另外,如果没有T
中的shuffle()
声明,是否可以做同样的事情?
您可以将类型参数移动到类型成员,这有时可以使您不必在仅内部使用它们时指定它们。
这是一个主意:
object Pile {
def apply(deck0: Deck): Pile { type D = deck0.type } = new Pile {
val deck = deck0
type D = deck0.type
val cards = deck.cards.toList
}
}
trait Pile { self =>
type D <: Deck
type Self = Pile { type D = self.deck.type }
val deck : D
def cards: List[deck.Card]
def shuffle(shuffler: Shuffler): Self = shuffler.shuffle(this)
}
object Deck {
def apply[A1](values: Set[A1]): Deck { type A = A1 } = new Deck {
type A = A1
val cards = values.map(Card(_))
}
}
trait Deck {
type A
case class Card(value: A)
def cards: Set[Card]
}
trait Shuffler {
def shuffle(pile: Pile): pile.Self
}
object Shuffler {
def randomShuffler(r: util.Random): Shuffler = new Shuffler {
def shuffle(pile: Pile): pile.Self = new Pile {
type D = pile.deck.type
val deck = pile.deck
val cards = r.shuffle(pile.cards)
}
}
}
测试:
val deck = Deck(Set(1 to 10: _*))
val pile0 = Pile(deck)
pile0.cards
val sh = Shuffler.randomShuffler(util.Random)
val pile1 = pile0.shuffle(sh)
pile1.cards
如您所见,强制依赖于值的类型并非易事,因此问题是您是否确实需要它们,或者可以为
A
使用简单的类型参数确定。例如,上面的方法并不能防止您将同一张卡不小心两次放入一堆。关于scala - Scala内部类输入,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41402246/