Scala - designation of a matched item in pattern matching
You can use @
to bind the whole pattern to variable in your version
class Animal(hair: Option[Hair])
case class Cat(var hair: Option[Hair]) extends Animal(hair)
case class Dog(var hair: Option[Hair]) extends Animal(hair)
case class Sheep(var hair: Option[Hair]) extends Animal(hair)
def what(animal: Animal) {
animal match {
case Cat(hair) => println("processing cat, hair=" + hair)
case Dog(hair) => println("processing dog, hair=" + hair)
case s @ Sheep(hair) => {
println("processing sheep, cutting hair...")
//cut(hair)
s.hair = None
}
}
}
But you don't have to use var
. Here is more functional version of your snippet. what
here just returns Sheep
with None
Hair
after cutting.
trait Animal
case class Cat(hair: Option[Hair]) extends Animal
case class Dog(hair: Option[Hair]) extends Animal
case class Sheep(hair: Option[Hair]) extends Animal
def what(animal: Animal): Animal =
animal match {
case Cat(hair) => {
println("processing cat, hair=" + hair)
animal
}
case Dog(hair) => {
println("processing dog, hair=" + hair)
animal
}
case Sheep(hair) => {
println("processing sheep, cutting hair...")
//cut(hair)
Sheep(None)
}
}
}
this does not work, because in the pattern matching the var "hair" is just extracted from the Sheep object so it is not the field of Sheep, but a variable in the context of the case block. You could do it like this:
class Hair
trait Animal {
var hair: Option[Hair]
}
case class Cat(var hair: Option[Hair]) extends Animal
case class Dog(var hair: Option[Hair]) extends Animal
case class Sheep(var hair: Option[Hair]) extends Animal
//then somewhere else:
def what(animal: Animal) {
animal match {
case Cat(hair) => println("processing cat, hair=" + hair)
case Dog(hair) => println("processing dog, hair=" + hair)
case Sheep(hair) => {
println("processing sheep, cutting hair...")
animal.hair = None
}
}
}
Just tell Animal it has a mutable field hair and you can set it without casting it to the right type.