Implicit resolution of dependent types in Scala

Consider the following code snippet:

trait Foo {
  type T
  def value: T
}

object Foo {
  def apply[A](v: A): Foo = new Foo {
    override type T = A
    override def value = v
  }
}

trait Decode[A] {
  def apply(x: A): String
}

object Decode {
  def apply[A](f: A => String): Decode[A] = new Decode[A] {
    override def apply(x: A) = f(x)
  }

  implicit val decodeStr: Decode[String] = Decode(identity)
}

class Sandbox {
  def decodeFoo(foo: Foo)(implicit decoder: Decode[foo.T]): String =
    decoder(foo.value)

  val foo = Foo("hello")
  println(decodeFoo(foo))
}

The above code should work fine and print hello, but instead it will not compile:

could not find implicit value for parameter decoder: Decode[Sandbox.this.foo.T]
[error]   println(decodeFoo(foo))

Even when I explicitly pass an implicit parameter:

println(decodeFoo(foo = foo)(decoder = Decode.decodeStr))

I still get this error:

type mismatch;
[error]  found   : Decode[String]
[error]  required: Decode[Sandbox.this.foo.T]
[error]   println(decodeFoo(foo = foo)(decoder = Decode.decodeStr))
[error]                                                 ^

Of course, I can do Fooa Foo[T]and define the decoders for it, but this is not the point of this question - I want to understand why the code above is not compiled.

+4
source share
1 answer

The problem exists here:

object Foo {
  def apply[A](v: A): Foo = new Foo {
    override type T = A
    override def value = v
  }
}

, Foo, , , Foo. , , Foo T. Aux, , Foo (, ...)

object Foo {
  type Aux[A] = Foo{ type T = A }

  def apply[A](v: A): Aux[A] = new Foo {
    type T = A
    def value = v
  }
}

, A Foo, T A.

+5

Source: https://habr.com/ru/post/1688827/


All Articles