Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Structural type in method type parameterization in Scala?

Tags:

scala

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?

like image 918
Jus12 Avatar asked Sep 29 '11 20:09

Jus12


1 Answers

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.

like image 99
Ben James Avatar answered Nov 16 '22 00:11

Ben James