简体   繁体   English

传递性的暗示 - 这在Scala中是否可能?

[英]transitive implicits - is this possible in Scala?

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 . 假设我需要从AB的转换,我会调用func1 But when I need a conversion from A to D I would like to have a composition of those functions. 但是当我需要从AD的转换时,我希望有这些函数的组合。 Is such thing possible in a dynamic notion? 在动态的概念中,这样的事情是否可能?

From the Scala documentation for language features , explaining why implicit conversions have to be explicitly enabled in 2.10: 语言功能的Scala 文档中 ,解释了为什么必须在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. 我们从未明确定义从整数到字符串的转换器,但编译器能够使用我们的composeMyConverters方法在需要时构造一个。

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. 与隐式转换一样,这种方法也可能被滥用,但要更加容易地了解转换器的范围,应用位置等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM