Frage

I have a very simple case class called FooPosition:

case class FooPosition(x: Int, y: Int)

and a Foo class that has a FooPosition. I am interested in creating a function that returns -1 only for coordinates that are equal to (x-1, y) with respect to a Foo object and returns 0 everywhere else. So I wrote:

class Foo(position: FooPosition) {
  def bar = (p: FooPosition) => p match {
    case FooPosition(position.x - 1, position.y) => -1
    case FooPosition(_, _) => 0
  } 
}

which results in an error that says "Not found: value -". Interestingly,

val myFoo = FooPosition(1, 0)
val newFoo = FooPosition(myFoo.x - 1, myFoo.y)

works just fine. I'm obviously missing something about pattern matching here (since I am a beginner). But what would be an elegant solution to this problem? I have worked around the problem using

class Foo(position: FooPosition) {
  private val left = FooPosition(position.x - 1, position.y)
  def bar = (p: FooPosition) => p match {
    case `left` => -1
    case FooPosition(_, _) => 0
  }
}

but I think there must be a better way.

Thanks in advance.

War es hilfreich?

Lösung

You can't use such syntax in pattern matching. But here are two options -- first one is to use guards:

def bar = (p: FooPosition) => p match {
  case FooPosition(x, _) if (x == p.x - 1) => -1
  case _ => 0
} 

Here _ denotes anything, I don't care about the actual value.

Second is to do match-by-value (values with capitalized name will be matched by it's value, instead of producing new alias):

def bar = (p: FooPosition) => {
    val Px = p.x - 1
    p match {
      case FooPosition(Px, _) => -1
      case _ => 0
    }
} 

Finally, your code will always default to 0 -- you're feeding some point p to it and then expecting it's X coordinate to be one unit less. Perhaps, you should write

def bar(p: FooPosition) = p match {
      case FooPosition(x, _) if (x == p.x -1) => -1
      case _ => 0
} 

instead

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top