transitive implicits - is this possible in Scala?

2019-05-18 03:56发布

Let's say I have several functions:

func1 : A => B

func2:  B => C

func3:  C => D

I would like to orchestrate now functions when needed in a generic fashion.

let's say if i need a conversion from A to B I'd call func1. But when I need a conversion from A to D I would like to have a composition of those functions. Is such thing possible in a dynamic notion?

1条回答
Summer. ? 凉城
2楼-- · 2019-05-18 04:23

From the Scala documentation for language features, explaining why implicit conversions have to be explicitly enabled in 2.10:

Why control it? Implicit conversions are known to cause many pitfalls if over-used. And there is a tendency to over-use them because they look very powerful and their effects seem to be easy to understand. Also, in most situations using implicit parameters leads to a better design than implicit conversions.

User-defined implicit conversions are almost always a bad idea, and making them transitive would be much, much worse.

You can, however, use type classes to get a similar effect in a much safer, more controlled way. For example, suppose we have the following:

trait MyConverter[A, B] { def apply(a: A): B }

implicit def composeMyConverters[A, B, C](implicit
  ab: MyConverter[A, B],
  bc: MyConverter[B, C]
) = new MyConverter[A, C] { def apply(a: A) = bc(ab(a)) }

Now we can write:

implicit object doubleToString extends MyConverter[Double, String] {
  def apply(d: Double) = d.toString
}

implicit object intToDouble extends MyConverter[Int, Double] {
  def apply(i: Int) = i.toDouble
}

def convertToString[A](a: A)(implicit as: MyConverter[A, String]) = as(a)

And finally:

scala> convertToString(13: Int)
res0: String = 13.0

We've never explicitly defined a converter from integers to strings, but the compiler is able to use our composeMyConverters method to construct one when it's needed.

Like implicit conversions, this approach can also be abused, but it's much easier to keep tabs on what converters are in scope, where they're being applied, etc.

查看更多
登录 后发表回答