11

Consider the following Scala code (e.g., in REPL)

object A{def foo:Unit = {}}
object B{def foo:Unit = {}}

def bar[T <: Any {def foo: Unit}](param: T*):Unit = param.foreach(x => x.foo)

bar(A, A)  // works fine
bar(B, B)  // works fine
bar(A, B)  // gives error

The first two work fine. The third ones gives an error:

error: inferred type arguments [ScalaObject] do not conform to method bar's type parameter bounds [T <: Any{def foo: Unit}]

Are there any ways to do what I want?

1 Answer 1

14

This is usually called structural typing, not duck typing. I edited your title. :)

I think that your problem is caused by defining the type parameter T and then using it in an invariant way. T can only refer to one concrete type, but you have parameters of different types A and B.

This works:

 def bar(param: {def foo: Unit}*) = param.foreach(x => x.foo)

Edit: Using a type alias also works:

 type T = {def foo: Unit}
 def bar(param: T*) = param.foreach(x => x.foo)

This works because the compiler will simply substitute the structural type in place of its alias, T. After the substitution, this example is exactly the same as the one above.

Sign up to request clarification or add additional context in comments.

4 Comments

This is another one of those features that makes Scala so awesome.
Does it use reflection at runtime? I thought it should not use reflection because the error in my code occurs during compile.
It does use reflection at runtime. See Randall Schulz's explanation in this thread: scala-lang.org/node/6834
I believe that if the information is available at compile time, it should be possible to insert this information for use at runtime (unless I am missing something). Is there an example that can be exhibited to show that reflection is the only way to do it.

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.