Reputation: 1457
For the two blocks of code, i expected the self
reference in both blocks to be Foo[A]. However it seems the second block does not compile. Can someone explain to me how to resolve the self
references?
trait Foo[A] {
def format(value:A):String
def bar[B](f:B=>A):Foo[B] = {
val self = this
new Foo[B] {
override def format(value: B): String = self.format(f(value))
}
}
}
trait Foo[A] {
def format(value:A):String
val self = this
def bar[B](f:B=>A):Foo[B] = {
new Foo[B] {
override def format(value: B): String = self.format(f(value))
}
}
}
Upvotes: 1
Views: 69
Reputation: 12804
self
get assigned this
, which is a reference to a particular instance, the one you're calling a method (or a constructor) at invocation.
In the first snippet, you invoke the method bar
on an object of type Foo[A]
, meaning that at that point this
means the instance of Foo[A]
. After you assign this
to self
you proceed to create a new instance of Foo
, this time giving the type parameter a different type, but self
.
In the second snippet you are saying that objects of type Foo[A]
have a member field that is called self
and gets assigned this
. This will apply to all instances of Foo[_]
, regardless of how you call the type parameter. When you create a second Foo
calling the type parameter B
, this second instance will nonetheless have a member field self
, which gets assigned this
, which at this point is Foo[B]
and shades the self
that you declared as part of the initial declaration of Foo
.
This means that in the second snippet, you the format
method implementation of Foo[B]
has access to a self
reference of Foo[B]
itself, which causes the type error you mentioned.
bar
takes a function that takes a B
and transforms it into an A
f: B => A
to value: B
, turning it into an A
, then you try to feed A
to Foo[B]#format(value: B)
Sorry for the convoluted response; in short: type parameters are mere placeholder names for actual types just like value parameters are placeholder names for actual runtime values. Apply the same reasoning to both types and values and reasoning about them will become easier.
Upvotes: 2