I need a back-check (please).
In an article ( http://www.win-vector.com/blog/2010/06/automatic-differentiation-with-scala/ ) I just wrote I stated that it is my belief in Scala that you can not specify a function that takes an argument that is itself a function with an unbound type parameter. I have edited this question to try and simplify the example.
The following code works by introducing a trait GenericFn that imitates the Scala Function1 trait, except it has a free-type parameter in the function:
object TypeExample {
trait NumberBase {
def result:String
}
class A extends NumberBase {
def result = "A"
}
class B extends NumberBase {
def result = "B"
}
trait GenericFn {
def apply[X<:NumberBase](x:X):String
}
def specializeAndApplyTwice(f:GenericFn):String = {
f[A](new A()) + f[B](new B())
}
def main(args : Array[String]) : Unit = {
val f = new GenericFn {
def apply[X<:NumberBase](x:X):String = { x.result }
}
println(specializeAndApplyTwice(f))
}
}
This works, but is there a way to do this without the GenericFn trait (use a standard function notation)? For example the code below fails with the compile-time error: "type mismatch; found : TypeExample2.A required: _$1 where type _$1 <: TypeExample2.NumberBase":
def specializeAndApplyTwice(f:(_<:NumberBase)=>String):String = {
f(new A()) + f(new B())
}
Restating the initial motivation for the question: We want to give a type to a value 'g' because we want to pass it around. Scala values (of course) cannot have polymorphic type, even if they are function values. So how to give a type where some part of it is unknown?
So I believe one solution is to use wildcards (a form of existential abstraction):
def g(f: Array[_ <: NumberBase[_]] => Double, z: Array[Double]): Double
The prose explanation for the type of g is: a function from Array[T] and Array[Double] to Double, where T is some type that extends Double. "some" is the word that indicates existential abstraction, we ask that such a type exists although we do not care at this point which one it is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With