0

I have the following code, and I was wondering why the list.head.effects = part is necessary here. To my understanding, uniform access princile says that the list should be returned by just the list.head.effects, at which point I could access the list. But to make the assignment actually work, I need to have it as it is below. Would it be that it evaluates the Entrance :: list.head.effects but does not assign it anywhere? Am I still too deep in the mutable world?

def addEntrance(list: List[Tile]) = list.head.effects = Entrance :: list.head.effects

case class Tile(x: Int, y: Int) {
  var effects: List[_ >: Effect] = List()
}

case class Entrance extends Effect

In any case, is there a nicer way to do this?

Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
Zavior
  • 6,412
  • 2
  • 29
  • 38

1 Answers1

3

:: creates a new list where the left argument is prepended to the list on the right. This does not change or assign anything. An immutable solution without the var could be:

case class Tile(x: Int, y: Int, effects: List[_ >: Effect] = List())

case class Entrance extends Effect

def addEntrance(list: List[Tile)) = list match {
  case Tile(x,y,effects) :: tail => Tile(x,y,Entrance() :: effects) :: tail
  case Nil => ...
}

Here addEntrance returns an updated list, which is the way to work with immutable lists.

By the way: Using .head on a list is only for special cases because usually you don't know whether the list has at least one item. So using pattern matching is a better approach here.

Martin Ring
  • 5,404
  • 24
  • 47