0

I'm attempting to match a lists first two elements, however, it wont accept lists of arbitrary length. The below code fails.

  def demoCases() = {
    def actor1 = new Actor[Employee] {}
    def actor2 = new Actor[Employee] {}
    def actor3 = new Actor[Animal] {}

    var actors = List(actor1, actor2, actor3);
    println();
    actors match {
      case (_: Employee) :: (_: Employee) :: tail
        => {println("nice 2  employees to start with ")};

      case Nil
        => {println("no match")}
    }

The exception :

Exception in thread "main" scala.MatchError: List(.....)

How can i specify that only the two elements first of the list need to match this expression?

elm
  • 20,117
  • 14
  • 67
  • 113
jayunit100
  • 17,388
  • 22
  • 92
  • 167

2 Answers2

1

Just replace case Nil by case _ => println("no match"). _ as a pattern means "match anything". But note that your first case requires that the first two elements of the list are Employees, not Actors.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • The original goal is to match on the generic type (i.e. match employee,employee but not employee,animal). Is that possible ? Its appearing not to be possible to match on generic types. It appears that http://stackoverflow.com/questions/16056645/how-to-pattern-match-on-generic-type-in-scala has a more apropos solution. – jayunit100 Aug 10 '14 at 00:45
  • actuallly, looking further, it appears my original intent, which is to match by the generic type, might not be possible at all ? – jayunit100 Aug 10 '14 at 01:15
  • Yes, it's impossible in general. There are workarounds if you control the definition of `Actor`, as mentioned in the question you linked. – Alexey Romanov Aug 10 '14 at 05:18
1

The following does not work thanks to type-erasure (pointed out by Alexey Romanov)

case (_: Actor[Employee]) :: (_: Actor[Employee]) :: tail

Therefore I cannot think of any way to do what you want without restructuring the code. For example if you made Employee a member of Actor somehow, and made Actor a case class, you could do

case Actor(_: Employee) :: Actor(_: Employee) :: tail
samthebest
  • 30,803
  • 25
  • 102
  • 142
  • This won't work as desired thanks to type erasure. It'll only check that elements are `Actor[_]`, not `Actor[Employee]`. – Alexey Romanov Aug 07 '14 at 05:22
  • @AlexeyRomanov thanks for the feedback. this is a tempting and instructive answer (hence the upvote), but not the precise solution. – jayunit100 Aug 10 '14 at 00:27