2
votes

I thought implicits in the companion object would be found. What's wrong with this?

object Elsewhere{
    case class NamedInt(i: Int, name: String)
    object NamedInt{
        implicit class ToNamedInt(i: Int){
            def named(name: String) = NamedInt(i, name)
        }
    }
}

object Application{
    import Elsewhere.NamedInt

    //Error: value named is not a member of Int
    val named: NamedInt = 3.named("bob") 
}

Update: I realise I can import the implicit class directly, but I thought it should compile without it since the implicit is in the companion object. E.g. this works without an extra import

object Elsewhere{
    case class MyInt(i: Int)
    object MyInt{
        import scala.language.implicitConversions
        implicit def myIntToSome(t: MyInt): Some[Int] = Some(t.i)
    }

}

object Application{
    import Elsewhere.MyInt

    val o: Option[Int] = MyInt(1) 
}

Update 2:

Jesse Eichar comments on his blog:

You are confusing implicit parameter resolution with implicit object conversion. Implicit object conversion is potentially dangerous so they normally have to be imported explicitly into scope.

Caveats to that is implicit object conversions defined in superclasses and (I am pretty sure) in package objects are automatically in scope.

This would make sense to me, but then why does the MyInt example above work?

1

1 Answers

2
votes

Adding one extra line fixes things (you need to also explicitly import the companion object fields):

object Application{
    import Elsewhere.NamedInt
    import Elsewhere.NamedInt._

    // Compiles OK now :)
    val named: NamedInt = 3.named("bob")
}