gpt4 book ai didi

Scala 内部类类型

转载 作者:行者123 更新时间:2023-12-01 23:17:27 26 4
gpt4 key购买 nike

假设我有以下内容:

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))
}
}
}

如果没有 Pile 中的 val Deck 声明,是否可以做同样的事情?另外,如果没有 shuffle() 中的 T 声明,是否可以做同样的事情?

我一直在尝试诸如 pile: x.Pile forSome {val x: Deck[_]} 之类的东西,但由于打字问题,它们似乎无法编译(阅读:我没有完全理解其中的语义),并且我试图避免重写 Shuffler 来使用原始列表(无论如何,我该如何表达?List[Deck[T] ]#Card] 并不完全存在,因为我想要来自同一 DeckCard 列表)。

最佳答案

Is it possible to do the same thing without having the val deck declaration in Pile?

如果我们想要强制执行您似乎想要的值依赖类型(例如,两个 Pile[Int] 仅当它们引用相同的牌组时才兼容值)。

Also, is it possible to do the same thing without the T declaration in 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 内部类类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41402246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com