2

During daily Scala coding I faced an issue that Scala implicits resolution depends on declaration order. A simple example:

object example extends App { trait FooTypeClass[T] { def foo: T } def bar[T](implicit tc: FooTypeClass[T]) = println(tc.foo) class A { // bar[A] doesn't compile } object A { implicit object aFoo extends FooTypeClass[A] { def foo: A = new A { override def toString = "a" } } } bar[A] } 

It does compile, but if I uncomment the commented line, it won't find the required implicit in scope. So, to make it compile I should place object A declaration before class A. That means my companions should go before their classes but I'd rather leave them as they are in the example.

Why does this order matter? Is there a workaround for this?

1 Answer 1

1

A possible workaround keeping the order you wished:

object A { implicit val aFoo: FooTypeClass[A] = new FooTypeClass[A] { def foo: A = new A { override def toString = "a" } } } 

I keep on seeking for the explanation why object (instead of val) doesn't fit.

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

7 Comments

Wow, it's interesting: if I omit type declaration after val aFoo, it won't compile as well. In fact, it infers aFoo's type to be FooTypeClass[A] with Object {def foo: A} - some structural stuff. Type declaration fixes this. Still curious why implicit object doesn't work.
object Foo extends Bar implicitly creates anonymous class which extends Bar, so this seems to be identical to val foo = new Foo with Bar without type annotation. The questions is: why doesn't the compiler resolve its type to be FooTypeClass[A] and uses that structural type instead which looks much more complicated.
In general case, instantiating a trait trait Foo with new Foo {} gives back an instance of Foo with Object class. But this is not the case for abstract class. So, looks like this is the intentional compiler behavior. Interesting though...
Still can't understand why does changing the order fix the issue without changing object to val.
Implicits without explicit return types are not eligible in implicit searches higher up in the same file. Without this rule, the typechecker runs into cycles very quickly. Implicit object cannot have an explicit type ascribed; my recommendation is to avoid them in favour if implicit vals.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.