Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specialize a type parameterized argument to multiple different types for in Scala?

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())
}
like image 943
jmount Avatar asked Jun 15 '10 18:06

jmount


1 Answers

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[_ &lt: 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.

like image 190
buraq Avatar answered Nov 15 '22 04:11

buraq