5

Consider the following piece of code:

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 fails to compile:

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

Even when I explicitly pass in the implicit param:

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

I still get this error now:

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

Ofcourse, I can make Foo a Foo[T] and define decoders for it but that's not the point of this question - I want to understand why the above code fails to compile.

1 Answer 1

5

The problem exists here:

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

There, you've established that you will return a Foo but not, specifically, which Foo. Hence, that function only knows that it can return a Foo for any type T. You need an Aux pattern to recapture the type which is lost when establishing your new Foo (yes, yes...)

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

which then says that for a given A produce the Foo which has it's T dependent type set to A.

Sign up to request clarification or add additional context in comments.

1 Comment

Or directly def apply[A](v: A): Foo { type T = A } = new Foo { ... }.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.