Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why implicit conversion doesn't work here?

I have this kind of code

trait Outer1 {
  type Inner1
}

trait Outer2 {
  type Inner2

  val ev: Outer1#Inner1 =:= Inner2

  def f: Outer1#Inner1
}


object Main {

//  My Problem here  
//  def test1(o2: Outer2): o2.Inner2 =
//    o2.f                                  // <- type mismatch

  def test2(o2: Outer2): o2.Inner2 =
    o2.ev.apply(o2.f)
}

Is there any chance to make test1 work? Why Scala compiler can't see ev and apply it implicitly?

like image 880
Artem Pelenitsyn Avatar asked Mar 24 '26 12:03

Artem Pelenitsyn


1 Answers

Two problems: First of all, your evidence parameter is not implicit, and therefore also not implicitly found by the compiler:

trait Outer1 {
  type Inner1
}

trait Outer2 {
  type Inner2

  implicit val ev: Outer1#Inner1 =:= Inner2

  def f: Outer1#Inner1
}

Second problem, a member of a value is not part of the standard implicit lookup scope. So you need to import that:

object Main {
  def test1(o2: Outer2): o2.Inner2 = {
    import o2.ev  // !
    o2.f
  }
}

EDIT: Abstract type checking notwithstanding, if I'm not mistaken, there is no way you can actually materialise Outer2, because how are you going to give evidence that its member Inner2 equals Outer1#Inner1 when Inner1 is abstract? That is why I am asking for the concrete scenario, because from this abstract layout, I'm not sure you are going to get anywhere.

As far as I can see, the evidence would only make sense for a dependent type, e.g.

trait Outer1 {
  type Inner1
  def bar: Inner1
}

trait Outer2 {
  type Inner2
  val outer1: Outer1 { type Inner1 = Inner2 }

  def foo: Inner2 = outer1.bar
}
like image 50
0__ Avatar answered Mar 27 '26 03:03

0__



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!