Your problem is that the square is not a function (i.e. a scala.Function1 [T, T] aka (T) => T). Instead, it is a type parameterized method with several lists of arguments, one of which is implicit ... there is no syntax in Scala to define an exactly equivalent function.
Interestingly, using the Numeric Type class means that the usual encodings of high-level functions in Scala are not directly applied here, but we can adapt them to this case and get something like this,
trait HigherRankedNumericFunction { def apply[T : Numeric](t : T) : T } val square = new HigherRankedNumericFunction { def apply[T : Numeric](t : T) : T = implicitly[Numeric[T]].times(t, t) }
This gives us a higher level “function” with its type parameter limited to the “Numeric” parameter,
scala> square(2) res0: Int = 4 scala> square(2.0) res1: Double = 4.0 scala> square("foo") <console>:8: error: could not find implicit value for evidence parameter of type Numeric[java.lang.String] square("foo")
Now we can define twice in terms of HigherRankedNumericFunctions,
def twice[T : Numeric](f : HigherRankedNumericFunction, a : T) : T = f(f(a)) scala> twice(square, 2) res2: Int = 16 scala> twice(square, 2.0) res3: Double = 16.0
The obvious drawback of this approach is that you lose the literal multiplicity of the Scala monomorphic function.
Miles sabin
source share