0

I deal with Scala problem which I can't properly name, so maybe there is already answer somewhere here (please be patient).

Assuming this code:

class A {def foo() = 5}
class B {def foo() = 6}
def fooer[T](x:T) = x.foo()

I get error:

<console>:7: error: value foo is not a member of type parameter T
    def fooer[T](x:T) = x.foo

This perfectly makes sense as compiler can't possibly know what type T will be passed. So finally the question - how can I implement typed function so it accepts only types with foo method declared?

Please note that I don't seek enum alternitives (see doc) as I don't know how many classes are there (external library). Also the classes have no common predecessor class or trait and they can't be modified.

Is this even possible? C++ language support this behavior using templates. I prefer solution which doesn't use reflection API.

Thanks :)

I tried some more definitions of fooer such as

def fooer[T <: {def foo(): Integer}](x:T) = x.foo()
fooer[A](new A)
<console>:10: error: type arguments [A] do not conform to method fooer's type parameter bounds [T <: AnyRef{def foo(): Integer}]
          fooer[A](new A)
               ^

but with no success

petrbel
  • 2,428
  • 5
  • 29
  • 49
  • Lee's answer matches the question nicely. Though I recommend you also look up ad-hoc polymorphism http://stackoverflow.com/questions/4465948/what-are-scala-context-and-view-bounds – samthebest Aug 23 '14 at 10:22

1 Answers1

5

The problem is that A.foo returns an Int not an Integer. If you change your method to:

def fooer[T <: {def foo(): Int}](x:T) = x.foo()

then it will work.

Lee
  • 142,018
  • 20
  • 234
  • 287
  • 2
    You could also simplify to `def fooer(x: { def foo(): Int }) = x.foo()` – Ben Reich Aug 22 '14 at 18:43
  • 3
    This does use reflection under the hood. But without C++ style templates and all the code generation that entails, there's no way to avoid it. – Rex Kerr Aug 22 '14 at 19:21