- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Implicit resolution spec (wording may not be strong enough)
Fri, 2011-04-08, 04:23
So there's a fun part of the spec that talks about implicit resolution.
That's where the spec states that it uses the parts of type T to look for implicits, and that it uses the rules of static resolution in the event of failure. Well, I have the following:
trait TypeClass[T] { def one(t : T) : Unit def two(t : T) : Unit}trait LowPriorityMagic { implicit def troublemaker[T <: { def one() : Unit }] = new TypeClass[T] { def one(t : T) = t.one() def two(t : T) = println("No two on this T") }} object TypeClass extends LowPriorityMagicclass OneTwoPunch { def one() = println("ONE") def two() = println("TWO")}object OneTwoPunch { implicit object MyTypeClass extends TypeClass[OneTwoPunch] { def one(t : OneTwoPunch) = t.one() def two(t : OneTwoPunch) = t.two() }}def foo[T](t : T)(implicit tc : TypeClass[T]) = { tc.one(t); tc.two(t);}
foo(new OneTwoPunch) // ONE! TWO!
Which is working right now, however I'm afraid that the wording is not strong enough to prevent a breaking change, such that the troublemaker implicit in LowPriorityMagic gets called.
Is there anyway we can guarantee that given a lookup of:
T[A,B]
U <: TV <: AX <: B
T, A and B companions will be searched first before U, V and X? Is the spec actually stating that it performs a lookup on (T with A with B) and checks for conflicts and then (U with V with X)?
Sorry for the random spec questions, but I'm very curious. I don't want my current design to be implementation dependent.
That's where the spec states that it uses the parts of type T to look for implicits, and that it uses the rules of static resolution in the event of failure. Well, I have the following:
trait TypeClass[T] { def one(t : T) : Unit def two(t : T) : Unit}trait LowPriorityMagic { implicit def troublemaker[T <: { def one() : Unit }] = new TypeClass[T] { def one(t : T) = t.one() def two(t : T) = println("No two on this T") }} object TypeClass extends LowPriorityMagicclass OneTwoPunch { def one() = println("ONE") def two() = println("TWO")}object OneTwoPunch { implicit object MyTypeClass extends TypeClass[OneTwoPunch] { def one(t : OneTwoPunch) = t.one() def two(t : OneTwoPunch) = t.two() }}def foo[T](t : T)(implicit tc : TypeClass[T]) = { tc.one(t); tc.two(t);}
foo(new OneTwoPunch) // ONE! TWO!
Which is working right now, however I'm afraid that the wording is not strong enough to prevent a breaking change, such that the troublemaker implicit in LowPriorityMagic gets called.
Is there anyway we can guarantee that given a lookup of:
T[A,B]
U <: TV <: AX <: B
T, A and B companions will be searched first before U, V and X? Is the spec actually stating that it performs a lookup on (T with A with B) and checks for conflicts and then (U with V with X)?
Sorry for the random spec questions, but I'm very curious. I don't want my current design to be implementation dependent.
Fri, 2011-04-08, 05:17
#2
Re: Implicit resolution spec (wording may not be strong enough)
Yes, I apologize.
U V and X are supertypes of T, A and B respectively.
On Thu, Apr 7, 2011 at 11:51 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
U V and X are supertypes of T, A and B respectively.
On Thu, Apr 7, 2011 at 11:51 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I think you inverted the relationship of U, V and X to T, A and B. Shouldn't it be U >: T?
On Fri, Apr 8, 2011 at 00:22, Josh Suereth <joshua.suereth@gmail.com> wrote:
So there's a fun part of the spec that talks about implicit resolution.
That's where the spec states that it uses the parts of type T to look for implicits, and that it uses the rules of static resolution in the event of failure. Well, I have the following:
trait TypeClass[T] { def one(t : T) : Unit def two(t : T) : Unit}trait LowPriorityMagic { implicit def troublemaker[T <: { def one() : Unit }] = new TypeClass[T] { def one(t : T) = t.one() def two(t : T) = println("No two on this T") }} object TypeClass extends LowPriorityMagicclass OneTwoPunch { def one() = println("ONE") def two() = println("TWO")}object OneTwoPunch { implicit object MyTypeClass extends TypeClass[OneTwoPunch] { def one(t : OneTwoPunch) = t.one() def two(t : OneTwoPunch) = t.two() }}def foo[T](t : T)(implicit tc : TypeClass[T]) = { tc.one(t); tc.two(t);}
foo(new OneTwoPunch) // ONE! TWO!
Which is working right now, however I'm afraid that the wording is not strong enough to prevent a breaking change, such that the troublemaker implicit in LowPriorityMagic gets called.
Is there anyway we can guarantee that given a lookup of:
T[A,B]
U <: TV <: AX <: B
T, A and B companions will be searched first before U, V and X? Is the spec actually stating that it performs a lookup on (T with A with B) and checks for conflicts and then (U with V with X)?
Sorry for the random spec questions, but I'm very curious. I don't want my current design to be implementation dependent.
--
Daniel C. Sobral
I travel to the future all the time.
On Fri, Apr 8, 2011 at 00:22, Josh Suereth <joshua.suereth@gmail.com> wrote:
--
Daniel C. Sobral
I travel to the future all the time.