4

Suppose c can be Updatable or Drawable or both. If it's both, I want to handle Updatable first.

Given this code:

case c: Updatable => c.update()
case c: Drawable => c.draw()

Has one problem: it only evaluates one of the choices. Sometimes, c can be both so I need to run both of these.

I know there's | mechanism that looks like this:

case c @ (_: Updatable | _: Drawable) => c.update(); c.draw()

The problem here is that I can't call both update and draw because it's an |.

I think I'm looking for something like this, but doesn't compile:

case c @ (_: Updatable & _: Drawable) => c.update(); c.draw()
case c: Updatable => c.update()
case c: Drawable => c.draw()

Is there such a thing? I know I could open it up and write isInstacenOf, but I'd prefer a pattern match if it's even possible.

2 Answers 2

6
def f(c:Any) = c match {
  case d:Drawable with Updatable => println("both")
  case d:Drawable => println("drawable")
  case u:Updatable => println("updatable")
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is a fantastic idea, why did I not think of this? ;)
The with keyword used in this context is conjunction (obviously). If you're interested in disjunctive / union types, check out this fantastic blog: chuusai.com/2011/06/09/scala-union-types-curry-howard
5

How about this?

trait Foo
trait Bar
class FooBarImpl extends Foo with Bar
type FooBar = Foo with Bar


def matching(x: Any) = x match {
    case _: FooBar  => "i'm both of them"
    case _: Foo    => "i'm foo"
    case _: Bar    => "i'm bar"
}

val x = new FooBarImpl

matching(x) 
// res0: String = i'm both of them
matching(new Foo{})
// res1: String = i'm foo

Although I'm not quite sure whether reflection kicks in or not.

4 Comments

I think defining the union type is nice if you need to pattern match like this often, but for 1 single case I'm going with what Landei showed.
@KaiSellgren nothing stops you from writing case _: Foo with Bar without defining any external type alias ;-)
That is correct. Your answer is basically the same as what Landei did there. I happened to accept his answer due to the angle of the moon.
"Union" is a very poor choice for this construct. Union is typically interpreted as disjunctive while with is conjunctive.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.