Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala transitive implicit conversion

  • I have 3 Scala classes (A,B,C).
  • I have one implicit conversion from A -> B and one from B -> C.

At some point in my code, I want to call a C method on A. Is this possible? One fix I came up is to have a conversion from A -> C but that seems somewhat redundant.

Note:

  • When I call B methods on A it works.
  • When I call C methods on B it works.
  • When I call C methods on A it says that it didn't find the method in the body of A

Thanks ...

like image 329
Matei Alexandru Bogdan Avatar asked Mar 04 '12 18:03

Matei Alexandru Bogdan


People also ask

What is implicit conversion in Scala?

Implicit conversions in Scala are the set of methods that are apply when an object of wrong type is used. It allows the compiler to automatically convert of one type to another. Implicit conversions are applied in two conditions: First, if an expression of type A and S does not match to the expected expression type B.

What is the implicit conversion?

An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.

What is implicit data type conversion?

Implicit type conversion in C language is the conversion of one data type into another datatype by the compiler during the execution of the program. It is also called automatic type conversion.


2 Answers

It seems you made a typo when you wrote the question. Did you mean to say you have implicit conversions from A -> B and B -> C, and that you find an A -> C conversion redundant?

Scala has a rule that it will only apply one implicit conversion when necessary (but never two), so you can't just expect Scala to magically compose A -> B and B -> C to make the conversion you need. You'll need to provide your own A -> C conversion. It's not redundant.

like image 81
Ken Bloom Avatar answered Sep 18 '22 13:09

Ken Bloom


It does seem somewhat redundant, but the A -> C conversion is exactly what you should supply. The reason is that if implicits are rare, transitive chains are also rare, and are probably what you want. But if implicits are common, chances are you'll be able to turn anything into anything (or, if you add a handy-looking implicit, suddenly all sorts of behaviors will change because you've opened up different pathways for implicit conversion).

You can have Scala chain the implicit conversions for you, however, if you specify that it is to be done. The key is to use generics with <% which means "can be converted to". Here's an example:

class Foo(i: Int) { def foo = i }
class Bar(s: String) { def bar = s }
class Okay(b: Boolean) { def okay = b }
implicit def to_bar_through_foo[T <% Foo](t: T) = new Bar((t: Foo).foo.toString)
implicit def to_okay_through_bar[U <% Bar](u: U) = new Okay((u: Bar).bar.length < 4)

scala> (new Foo(5)).okay
res0: Boolean = true
like image 25
Rex Kerr Avatar answered Sep 18 '22 13:09

Rex Kerr