Search code examples
scalacompiler-errorsimplicit-conversionimplicitcompanion-object

Scala: Use implicits in companion object


I am creating companion object in scala and trying to use object implictis functions in class without import. But whenever, trying to compile the code I am getting an error: type mismatch; seems it is not able to import implictis automatically. Following is my code:

object ImplicitTest5 {
    implicit def dollarToRupa(dollar: Dollar): Rupa = { 
        println("calling .... dollarToEuro") 
        Rupa(dollar.value)
    } 

    implicit def dollarToEuro(dollar: Dollar): Euro = { 
        println("calling .... dollarToEuro") 
        Euro(dollar.value)
    } 
}

case class Dollar(value: Double)

case class Euro(value: Double)

case class Rupa(value: Double)

class ImplicitTest5 { 

    private val value = "String"

    def conversion = {
        val euro: Euro  = Dollar(3.1)
        println(s" ----- $euro")
    }
}

When i am using import ImplicitTest5._ in my class, it will compile and run fine. According to Programming in Scala, Page: 478 it will be working fine, and there is no need to define import.

In this case, the conversion dollarToEuro is said to be associated to the type Dollar. The compiler will find such an associated conversion every time it needs to convert from an instance of type Dollar. There’s no need to import the conversion separately into your program.

Something is going wrong with my sample or my understandings are misleading ?


Solution

  • Something is going wrong with my sample or my understandings are misleading

    The conversion to Dollar will be associated with it if you define it inside Dollars companion object. Currently, all your implicits are defined on ImplicitTest5, which isn't where the compiler looks for implicits in regards to the Dollar class. This forces you to explictly import the object containing those implicits. Instead, do:

    case class Dollar(value: Double)
    object Dollar {
      implicit def dollarToEuro(dollar: Dollar): Euro = {
        println("calling .... dollarToEuro")
        Euro(dollar.value)
      }
    }
    

    For more, see "Where does Scala look for implicits"