隐式函数无法注入

Impicit function can't be injected

我有以下代码:

case class Number (value:Int)

class Calculator {
  def performCalc( input:Number)(implicit calc: (Number=>Number) ) =  calc(input)
}

现在,当我在 specs2 测试中尝试这个:

class CalculatorTest extends mutable.Specification {
  "Calculator" should {
    "*  Accept explicit calculation parameter" in {
      implicit val addTwelve = (input: Number) => Number(input.value + 12)
      val calc = new Calculator()

      val result = calc.performCalc(Number(4))
      result must beEqualTo(16)
    }
  }
}

我希望 'addTwelve' 函数作为 performCalc 的参数隐式注入。但是,我遇到以下失败:

Error:(49, 42) ambiguous implicit values:
 both method $conforms in object Predef of type [A]=> <:<[A,A]
 and value addTwelve of type nl.example.Number => nl.example.Number
 match expected type nl.example.Number => nl.example.Number
      val result = calc.performCalc(Number(4))
                             ^

我做错了什么?应该可以使用隐式方法,对吗?

斯卡拉:2.11.7

是的,这在技术上是对隐式的有效使用,但它不是一个非常 strong 的用例。具体来说,有一个预先存在的隐式提供 Number=>Number。编译器无法判断您真正想要哪种隐式方法。

最好将此方法作为隐式类型的 "tag" 包装到特征中。

case class Number(value: Int)
trait CalcMethod {
  def perform(n: Number): Number
}
class Calculator {
  def performCalc(input:Number)(implicit calc: CalcMethod) = calc.perform(input)
}

class CalculatorTest extends mutable.Specification {
  "Calculator" should {
    "*  Accept explicit calculation parameter" in {
      implicit val addTwelve: CalcMethod = new CalcMethod { 
          def perform(input: Number) = Number(input.value + 12) 
      }
      val result = new Calculator().performCalc(Number(4))
      result must beEqualTo(16)
    }
  }
}

编辑:

这可能更接近您想要的:

case class Number(value: Int)
implicit class CalcMethod(val perform: Number => Number)
class Calculator {
  def performCalc(input:Number)(implicit calc: CalcMethod) = calc.perform(input)
}

然后就可以这样使用了:

implicit val addTwelve: CalcMethod = (input: Number) => Number(input.value + 12) 
val result = new Calculator().performCalc(Number(4))