Can Scala allow free type parameters in arguments (is there a Scala Type Parameters of the first class of citizens?)?

I have a Scala code that does something different with two different versions of a function with parameters. I greatly simplified this from my application, but in the end my code full of form calls w(f[Int],f[Double]), where w()is my magic method. I would like to have a more magical method, for example z(f) = w(f[Int],f[Double]), but I cannot get any syntax, for example, z(f[Z]:Z->Z)to work, how it looks (to me), since function arguments cannot have their own type parameters. Here is the problem as a Scala code snippet.

Any ideas? A macro could do this, but I don't think they are part of Scala.

object TypeExample {
  def main(args: Array[String]):Unit = {
    def f[X](x:X):X = x              // parameterize fn
    def v(f:Int=>Int):Unit = { }     // function that operates on an Int to Int function
    v(f)                             // applied, types correct
    v(f[Int])                        // appplied, types correct
    def w[Z](f:Z=>Z,g:Double=>Double):Unit = {} // function that operates on two functions
    w(f[Int],f[Double])              // works
// want something like this:  def z[Z](f[Z]:Z=>Z) = w(f[Int],f[Double])
// a type parameterized function that takes a single type-parameterized function as an  
// argument and then speicalizes the the argument-function to two different types,  
// i.e. a single-argument version of w() (or wrapper)
  }
}
+5
3

:

trait Forall {
  def f[Z] : Z=>Z
}

def z(u : Forall) = w(u.f[Int], u.f[Double])

:

def z(u : {def f[Z] : Z=>Z}) = w(u.f[Int], u.f[Double])

, , .

EDIT: :

scala> object f1 {def f[Z] : Z=>Z = x => x}
defined module f1

scala> def z(u : {def f[Z] : Z=>Z}) = (u.f[Int](0), u.f[Double](0.0))
z: (AnyRef{def f[Z]: (Z) => Z})(Int, Double)

scala> z(f1)
res0: (Int, Double) = (0,0.0)

f1 extends Forall

scala> z(new Forall{def f[Z] : Z=>Z = x => x})
+6

, , , "rank-k polymorphism". wikipedia. k = 2. :

f[X](x : X) : X = ... 

, f "forall X.X → X"

, z, "(forall Z.Z → Z) → Unit". . wikipedia, 2- , 1. , . ( "" , ).

alexy_r, Scala, , , / parens. , , , :

//

object TypeExample {
  def main(args: Array[String]):Unit = {
    def f[X](x:X):X = x              // parameterize fn
    def v(f:Int=>Int):Unit = { }     // function that operates on an Int to Int function
    v(f)                             // applied, types correct
    v(f[Int])                        // appplied, types correct
    def w[Z](f:Z=>Z,g:Double=>Double):Unit = {} // function that operates on two functions
    w(f[Int],f[Double])              // works

//

    trait ForAll {
      def g[X](x : X) : X
    }

    def z(forall : ForAll) = w(forall.g[Int], forall.g[Double])
    z(new ForAll{def g[X](x : X) = f(x)})
  }
}
+6

I do not think that what you want to do is possible.

Edit:

My previous version was erroneous. It works:

scala> def z(f: Int => Int, g: Double => Double) = w(f, g)
z: (f: (Int) => Int,g: (Double) => Double)Unit

scala> z(f, f)

But of course, this is pretty much what you have.

I do not think that this is even possible for work, because type parameters exist only at compile time. There is no such thing at runtime. Therefore, it makes no sense for me to pass a parameterized function instead of a function with type parameters output using Scala.

And, no, Scala does not have a macro system.

+2
source

All Articles