简体   繁体   中英

Problems extending a ListSet with a concrete type

Trying to extend a ListSet with a concrete type in the Pile class, and then every time an ListSet[ConcreteType] instance is needed, I would pass an Pile instance

class Pile extends ListSet[Card]{
  def this(cards: ListSet[Card]){
    this()
    this ++ cards
  }
  def draw(amount: Int = 1): (Pile, Pile) = this.splitAt(amount)
}

In the 'draw' method, the compiler accuses 'Expression of type (ListSet[Card], ListSet[Card]) doesnt conform to the expected type(Pile, Pile)', but a simple:

type Pile = ListSet[Card]

inside the Pile body solves the problem .. I am really supposed to use the type alias AND the extend keyword? (id really like to create a new class instead of just giving an alias to it)

ps: Is my constructor looking like madness? It is the only way I can figure it out

The Problem is that splitAt returns ListSet[Card] , which is not a Pile, although your Pile extends ListSet[Card] .

A way to avoid this problem is the convert the result from splitAt to Pile s.

def draw(amount: Int = 1): (Pile, Pile) = {
  val (a,b) = this.splitAt(amount)
  (new Pile(a), new Pile(b))
}

Another Idea.

You only want to return Pile s in order to have the draw method available for the result. You could work with an implicit class here. Now all instances of ListSet[Card] have the draw method.

implicit class Pile(cards: ListSet[Card]) {
  def draw(amount: Int = 1) = cards.splitAt(amount)
}

Small example.

type Card = Int

val pile = ListSet(1,2,3,4,5)

val (drawn, remaining) = pile.draw()

val (nextDrawn, nextRemaining) = remaining.draw(2) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM