virtualeyes
virtualeyes

Reputation: 11237

Pattern Match Generic Return Type

EDIT
Leaving this for posterity, but nearly a year later, to get down voted, nice...would not do anything like the below now, but at the time, getting started with Scala, questions generally come from a place of ignorance....

ORIGINAL
I know I can just wrap a pattern match in a method with generic type specified like so:

def getTeam[T <: _Team](clazz: String): _Team =
  clazz match {
    case "roster" => new RosterController
    case "schedule" => new ScheduleController
  }

and get a meaningful type (_Team) for the compiler to work with.

However, I am wondering if it is possible to do this WITHOUT a wrapper method and without asInstanceOf[_Team] boilerplate? i.e. something other than

clazz match {
  case "roster" => new RosterController.asInstanceOf[_Team]
  case "schedule" => new ScheduleController.asInstanceOf[_Team]
}

Not the end of the world if not possible, but would prefer to do the matches in place vs. splitting into a separate method.

Thanks

Upvotes: 0

Views: 2365

Answers (2)

oxbow_lakes
oxbow_lakes

Reputation: 134270

I'm not sure what you think is going on in this method but it seems like you are either confused or have written the wrong thing down.

In your example, T is a type parameter, bounded above by the type _Team (which I assume is either a class or a trait). You subsequently ignore T, so it could be a phantom type but from your question, but it doesn't really seem like it.

You cannot possibly need to cast RosterController into a _Team because it either is one or it isn't. I can infer this because RosterController must be a concrete class as you are instantiating it. It's either a subtype of _Team or it is not.

If _Team is a trait, it can be mixed in:

new RosterController with _Team

But because you don't explain what you are trying to actually do, it's difficult to say for sure! Is RosterController also parameterized?


EDIT - from the comments below, it seems that you are wondering about what the compiler infers as the result type of an expression where that expression is a match statement.

Here's a useful example as to how the compiler can infer really quite a lot of cool stuff

scala> class Bar; class Baz; trait Foo
defined class Bar
defined class Baz
defined trait Baz

Now let's create a match expression:

scala> def foo(s: String) = s match {
   | case "a" => new Baz with Foo
   | case _   => new Bar with Foo
   | }
foo: (s: String)ScalaObject with Foo

So the compiler has correctly inferred Foo here. Perhaps you could rephrase your question, distilling in a REPL example exactly what you expect and how that differs from what actually happens.

Upvotes: 2

Alex
Alex

Reputation: 9438

trait _Team{ def doWhat_TeamCanDo(s:String){println s} }

class MyTeamString(clazz: String)

 implicit def getTeam: _Team =
  clazz match {
    case "roster" => new RosterController with _Team
    case "schedule" => new ScheduleController with _Team
 }
}

implicit def strToMyTeamString(s:String):MyTeamString= MyTeamString(s)

now you can "convert" any string to a _Team when you need it, implicitly:

"roster".doWhat_TeamCanDo("foo")

Upvotes: 1

Related Questions