简体   繁体   中英

Cannot call a function that accepts and returns an object of a self-referential parametrised type in a trait

Does anybody have an explanation for why the following invocation of foo() is illegal and returns the error:

trait Foo[T<:Foo[_]] {

  def foo(t: T): T

  def test_foo(t1: T, t2: T): T = {
    // produces error:
    //   type mismatch; 
    //   found: t2.type (with underlying type T) 
    //   required: _$1 where type _$1"
    t1.foo(t2) 
  }

}

From a human point of view it should be OK, since we have a function that accepts a type T and returns a type T. Then we have two objects t1 of type T and t2 of type T. One of the objects has method .foo() and the other is of the required type, so the call should be successful. What is wrong with this line of reasoning?

Good question. When you write T <: Foo[_] it translates to the existential type T <: Foo[X] forSome {type X} . The Scala compiler refers to the instance of X as _$1 to avoid collision with existing symbol names. In your example, both t1 and t2 have type T . When you call t1.foo you're treating t1 as a Foo[_$1] , so the expected parameter should have type _$1 . Instead, the compiler finds t2 with type T , which doesn't match. To fix the problem, you must place a more constrained type bound on T:

trait Foo[T <: Foo[T]] {
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM