Search code examples
scalajson4s

Why can JValue be implicitly converted to MonadicJValue even if jvalue2monadic is not imported?


In json4s, code can be written like this:

import org.json4s._
import org.json4s.jackson.JsonMethods._
...
val x: MonadicJValue = JObject()

This is correct because the function

implicit def jvalue2monadic(jv: JValue) = new MonadicJValue(jv)

is imported to the scope by the first import org.json4s._ line.

(source of jvalue2monadic defination on github)

However, I tried another segment of codes and it works well too:

import org.json4s.{JObject, MonadicJValue}
import org.json4s.jackson.JsonMethods.parse
...
val x: MonadicJValue = JObject()

Since the implicit function is not imported to this scope, I don't know how it works!


Solution

  • I finally got the answer from the post Where does Scala look for implicits?

    From the book "Programming in Scala, 2nd Edition" which is based on Scala 2.8, I learned the implicit rules that the scala compiler will look for implicit definitions in the companion object of the source or target types, however I didn't learn that the scala compiler will also look for implicit definitions in the outer object for nested types.

    In the question above, the implicit definition

    implicit def jvalue2monadic(jv: JValue) = new MonadicJValue(jv)

    is defined in the package object org.json4s, which is the outer object in the package hierachy nesting either JValue/JObject or MonadicJValue. So, jvalue2monadic will surely be used by the scala compiler when needed.