传递隐式-在Scala中可能吗?

Ste*_*nze 3 scala function implicit

假设我有几个功能:

func1 : A => B

func2:  B => C

func3:  C => D
Run Code Online (Sandbox Code Playgroud)

我想在需要时以通用方式协调功能。

假设我需要从转换为A,然后B致电func1。但是,当我需要从转换为时AD我希望将这些功能组合在一起。这样的事情在动态的观念中可能吗?

Tra*_*own 5

有关语言功能的Scala 文档中,解释了为什么必须在2.10中显式启用隐式转换:

为什么要控制它?如果使用过多,隐式转换会导致很多陷阱。而且有一种过度使用它们的趋势,因为它们看起来非常强大并且其效果似乎易于理解。同样,在大多数情况下,使用隐式参数比隐式转换可带来更好的设计。

用户定义的隐式转换几乎总是一个坏主意,使它们具有可传递性会变得非常糟糕。

但是,您可以使用类型类以更安全,更可控的方式获得相似的效果。例如,假设我们具有以下内容:

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)) }
Run Code Online (Sandbox Code Playgroud)

现在我们可以写:

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)
Run Code Online (Sandbox Code Playgroud)

最后:

scala> convertToString(13: Int)
res0: String = 13.0
Run Code Online (Sandbox Code Playgroud)

我们从未明确定义过从整数到字符串的转换器,但是编译器能够在需要时使用我们的composeMyConverters方法构造一个。

像隐式转换一样,这种方法也可以被滥用,但是更容易掌握范围内的转换器,应用的位置等。