Implicits for objects in Scala

I am confused by this description in “5.1.3 Implicit Resolution” in Joshua Suaret’s Scala book in depth, on page 100:

Scala objects cannot have companion objects for implicits. Because of this, it is implied that it is associated with an object type, which is desirable for the implicit volume of this object type to be provided from an external scope. Here is an example:

scala> object Foo { | object Bar { override def toString = "Bar" } | implicit def b : Bar.type = Bar |} defined module Foo scala> implicitly[Foo.Bar.type] res1: Foo.Bar.type = Bar 

But for now, I am making the Bar object implicit in the REPL:

 scala> object Foo { | implicit object Bar { | override def toString = "isBar" } | } defined module Foo scala> implicitly[Foo.Bar.type] res0: Foo.Bar.type = isBar 

It seems that he does not need to define the implicit in the external realm. Or do I think Joshua is completely wrong?

+6
source share
2 answers

In this scenario, the objects act as if they were their own companions, so you just need to embed your object objects, indicating the objects, in the body of the object itself,

 scala> object Bar { | override def toString = "Bar" | implicit def b : Bar.type = Bar | } defined module Bar scala> implicitly[Bar.type] res0: Bar.type = Bar 

Note that here the Bar body is considered as part of the implicit scope for resolving Bar.type .

This may seem like an obscure angle to a system like Scala, but I was able to use it in shapeless coding polymorphic (functional) values .

+8
source

If you put the following code in a file and try to compile it with scalac , it will fail with the 'implicit' modifier cannot be used for top-level objects

  implicit object Foo { object Bar { override def toString = "Bar" } } 

This, however, compiles fine:

  object Foo { implicit object Bar { override def toString = "Bar" } } 

I believe that using REPL implicit's not exactly the highest level, hence the apparent inconsistency.

+2
source

All Articles