kmh kmh - 4 months ago 19
Scala Question

scala polymorphic type for return value

How would I make this pattern work? func() fails to compile. I understand the problem with this setup, but what's a pattern that could accomplish basically this?

class A() {
val a: Int = 123
val b: String = "xxx"
}

def func[T](key: String, a: A): T = {
if (key == "a") a.a // would make T an Int
else if (key == "b") a.b // would make T a String
}

val a = new A()
func[Int]("a", a)
func[String]("b", a)

Answer

I'm not quite sure what you are going for, but a few possibilities.

class A() {
  val a: Int = 123
  val b: String = "xxx"
}

def func[T : Manifest](a: A) = implictly[Manifest[T]] match {
  case implicitly[Manifest[Int]]) => a.a
  case implicitly[Manifest[String]) => a.b
}

val a = new A()
func[Int](a)
func[String](a)

or

class A() {
  val a: Int = 123
  val b: String = "xxx"
}

val aKey = (_: A).a
val bKey = (_: A).b

def func[T](key: A => T, a: A) = key(a)

val a = new A()
func(aKey, a)
func(bKey, a)

or even with Shapeless,

import shapeless._
import syntax.singleton._
import record._

val a = ("a" ->> 123) :: ("b"  ->> "xxx") :: HNil

a("a") // typed as an Int
b("b") // typed as a String