0__
0__

Reputation: 67290

Breakdown with existential type and higher order function

Using some structure:

object Foo {
  trait Bar[B]
}
trait Foo[A, B, F <: Foo[A, B, F]] {
  def baz(fun: A => Foo.Bar[B] => Unit): Unit
}

...why are existential types causing trouble:

def test[A, F <: Foo[A, _, F]](foo: F) =
  foo.baz { a => b => println(b) } 

The following error occurs:

<console>:38: error: type mismatch;
 found   : A => Foo.Bar[(some other)_$1(in type F)] => Unit
   forSome { type (some other)_$1(in type F) }
 required: A => (Foo.Bar[_$1(in type F)] => Unit)
         foo.baz { a => b => println(b) } 
                     ^

While the following compiles:

def test[A, JamesClapperSociopath, F <: Foo[A, JamesClapperSociopath, F]](foo: F) =
  foo.baz { a => b => println(b) } 

Upvotes: 2

Views: 111

Answers (1)

Tobias Brandt
Tobias Brandt

Reputation: 3413

It must have something to do with equivalence of existential types. The compiler probably infers b: F#_$1 and then can't figure out that the two projections are equal.

Fortunately, functions are contravariant in the parameter type, so you can just write:

def test[A, F <: Foo[A, _, F]](foo: F) =
  foo.baz { a => (b: Any) => println(b) } 

Upvotes: 1

Related Questions