Haspemulator
Haspemulator

Reputation: 11308

Scala map with implicit conversion

I have a Scala case class and a corresponding Java class. I've declared an implicit conversion from Scala class to Java class. Now I have a Scala collection of Scala classes, and I want to convert them to Scala collection of Java classes. Is it possible with the implicit conversion? Here's what I've tried, naively perhaps:

case class PositionScala(latitude: Double, longitude: Double)
object PositionScala {
  implicit def toJava(p: PositionScala): Position = new Position(p.latitude, p.longitude) // Position is the Java class
}
...
val p: List[Position] = routeScala.shape.map(p => p) 
                     // routeScala.shape is List[PositionScala]

But it doesn't compile with the type mismatch error. Of course I can call the conversion function explicitly, but it defeats the purpose of using implicit converter. Is there a way to do what I want?

Upvotes: 0

Views: 1567

Answers (3)

Odomontois
Odomontois

Reputation: 16298

Additionally to @alexey-romanov 's answer I should make a stand for scala type resolution.

map method for scala collections have pretty complex behaviour. It tries to derive resulting collection\element type basing on visible CanBuildFrom implicit, so it can't say definitely what the result type of map argument should be. Because of that it can't apply implicit conversion here.

If for example you had

val posOpt: Option[PositionScala] = ???

and tried to apply

val posJava: Option[Position] = posOpt.map(p => p) 

It would found your conversion with no problem.

Upvotes: 1

Alexey Romanov
Alexey Romanov

Reputation: 170713

You need to put the type annotation in a different place: routeScala.shape.map(p => p: Position). But I'd say this is less clear than just writing routeScala.shape.map(PositionScala.toJava).

Upvotes: 4

Nyavro
Nyavro

Reputation: 8866

You can do it passing convertion function 'toJava' to map function:

val p: List[Position] = routeScala.shape.map(toJava)

Upvotes: 1

Related Questions