Can Scala allow free Type Parameters in arguments (are Scala Type Parameters first class citizens?)? - scala

I have some Scala code that does something nifty with two different versions of a type-parameterized function. I have simplified this down a lot from my application but in the end my code full of calls of the form w(f[Int],f[Double]) where w() is my magic method. I would love to have a more magic method like z(f) = w(f[Int],f[Double]) - but I can't get any syntax like z(f[Z]:Z->Z) to work as it looks (to me) like function arguments can not have their own type parameters. Here is the problem as a Scala code snippet.
Any ideas? A macro could do it, but I don't think those 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)
}
}

You can do it like this:
trait Forall {
def f[Z] : Z=>Z
}
def z(u : Forall) = w(u.f[Int], u.f[Double])
Or using structural types:
def z(u : {def f[Z] : Z=>Z}) = w(u.f[Int], u.f[Double])
But this will be slower than the first version, since it uses reflection.
EDIT: This is how you use the second version:
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)
For the first version add f1 extends Forall or simply
scala> z(new Forall{def f[Z] : Z=>Z = x => x})

If you're curious, what you're talking about here is called "rank-k polymorphism." See wikipedia. In your case, k = 2. Some translating:
When you write
f[X](x : X) : X = ...
then you're saying that f has type "forall X.X -> X"
What you want for z is type "(forall Z.Z -> Z) -> Unit". That extra pair of parenthesis is a big difference. In terms of the wikipedia article it puts the forall qualifier before 2 arrows instead of just 1. The type variable can't be instantiated just once and carried through, it potentially has to be instantiated to many different types. (Here "instantiation" doesn't mean object construction, it means assigning a type to a type variable for type checking).
As alexy_r's answer shows this is encodable in Scala using objects rather than straight function types, essentially using classes/traits as the parens. Although he seems to have left you hanging a bit in terms of plugging it into your original code, so here it is:
// this is your code
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
// This is new code
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)})
}
}

I don't think what you want to do is possible.
Edit:
My previous version was flawed. This does work:
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, it is pretty much what you have.
I do not think it is even possible for it to work, because type parameters exist only at compile-time. At run time there is no such thing. So it doesn't make even sense to me to pass a parameterized function, instead of a function with the type parameters inferred by Scala.
And, no, Scala has no macro system.

Related

How to hide implicit parameters in the middle on apply chain

Reduced example:
class Factory(x : Int) {
def apply(y : Int)(z : Int) : Int = x + y + z
}
class Sample {
def get[B <% Int](x : B) = new Factory(x)
}
val s = new Sample
What I want: s.get(2)(3)(4) should output 9. What I get
error: type mismatch;
found : Int(3)
required: Int => Int
s.get(2)(3)(4)
^
It is perfectly correct, compiler fails as it should. The second parameter list should contain implicit conversion, but it is omitted. Hence the error arises.
The question is how to make the compiler know that is should perform implicit resolution.
Things I've tried that does not work:
s.get(2)()(3)(4)
{s get 2}(3)(4)
(s get 2)(3)(4)
((s get 2))(3)(4)
Explicit way works, but it requires two lines instead of one:
val b = s get 2
b(3)(4)
I could also use the apply method explicitly: s.get(2).apply(3)(4) But it looks ugly.
How can I make compiler perform implicit resolution inside an expression?
You can use an explicit type ascription
val nine = (s.get(2): Factory)(3)(4)
Or if you find this inconvenient, build your own control structure for forcing type inference:
def infer[X](z: => X): X = z
val nineAgain = infer(s get 2)(3)(4)
s.get(2)(implicitly)(3)(4)
(implicitly is just a method defined in Predef: def implicitly[A](implicit x: A) = x.)

Scala currying and type inference

I'm trying to figure out how to use currying in Scala.
In the following snippet:
object Foo {
def foo(a:Int)(b:Int)(c:Int) : Int = a + b + c
def main(a:Array[String]) {
val f = foo(1)(2) _
def g : Int => Int = foo(1)(2)
// def h = foo(1)(2)
println(f(3))
println(g(3))
// println(h(3))
}
}
the definitions for f and g work, the one for h does not:
/home/vlad/Desktop/b.scala:9: error: missing arguments for method foo in object Main;
follow this method with `_' if you want to treat it as a partially applied function
def h = foo(1)(2)
What's the reasoning behind this being illegal? It seems to me that Scala should be able to figure out that after calling foo(1)(2) you'd be left with an Int => Int.
This is intended. If it were allowed (some languages really allow that), that would make it work when you forget to put an argument, and instead of compile-time error you would expect. This happens so often that scala authors decide to trade-off here and disallow this notation.
Martin told about that in his book, see "Why the trailing underscore?" http://www.artima.com/pins1ed/functions-and-closures.html#8.7

Scala - Make signature of function parameter f of higher order function g dependent on varars of g

I am trying to define a higher order function f which accepts a variable number of parameters args of type Wrapper[T]* and a function parameter g in Scala.
The function f should decapsulate each object passed in args and then call g with the decapsulated parameters. Therefore, g has to accept exactly the same number of parameters of type T as args contains.
The closest thing I could achieve was to pass a Seq[T] to g and to use pattern matching inside of g. Like the following:
f("This", "Is", "An", "Example")(x => x match {
case Seq(a:String, b:String, c:String): //Do something.
})
With f defined like:
def f[V](args: Wrapper[T]*)
(g: (Seq[T]) => (V)) : V = {
val params = args.map(x => x.unwrap())
g(params)
}
How is it possible to accomplish a thing like this without pattern
matching?
It is possible to omit the types in the signature of g
by using type inference, but only if the number of parameters is
fixed. How could this be done in this case?
It is possible to pass
different types of parameters into varargs, if a type wildcard is
used args: Wrapper[_]*. Additionally, casting the result of
x.unwrap to AnyRef and using pattern matching in g is
necessary. This, however, completely breaks type inference and type
safety. Is there a better way to make mixing types in the varargs
possible in this special case?
I am also considering the use of scala makros to accomplish these tasks.
Did I get you right? I replaced your Wrapper with some known type, but that doesn't seem to be essential.
def f[T, V](args: T*)(g: PartialFunction[Seq[T], V]): V = g(args)
So later you can do this:
f(1,2,3) { case Seq(a,b,c) => c } // Int = 3
Okay, I've made my own Wrapper to be totally clear:
case class Wrapper[T](val x:T) {
def unwrap = x
}
def f[V](args: Wrapper[_]*)(g: PartialFunction[Seq[_], V]): V =
g(args.map(_.unwrap))
f(Wrapper("1"), Wrapper(1), Wrapper(BigInt(1))) {
case Seq(s: String, i: Int, b: BigInt) => (s, i, b)
} // res3: (String, Int, BigInt) = (1,1,1)
Regarding your concerns about type safety and conversions: as you can see, there aren't any explicit conversions in the code above, and since you are going to pattern-match with explicitly defined types, you may not to worry about these things - if some items of an undefined origin are going to show in your input, scala.MatchError will be thrown.

Why do I need a curried function to be able to pass function literals with short placeholder syntax?

Given this definition:
class Foo(var x: String) {}
object Helper {
def model[T](get: ⇒ T, set: T ⇒ Unit) : Model[T] = new Model[T] {
override def getObject(): T = get
override def setObject(obj: T) { set(obj) }
}
}
I try to call model like this:
val f = new Foo("initial")
val stringModel = model(f.x, f.x = _)
But that doesn't work, the compiler gives me this, complaining about the underscore:
missing parameter type for expanded function ((x$1) => f.x = x$1)
If I change the definition of model to use two parameter lists like this:
def model[T](get: ⇒ T)(set: T ⇒ Unit) // rest is unchanged
Then I can call it like this:
model(f.x)(f.x = _)
Which I find nice and concise. I don't really mind doing it like this, though it makes method overloading harder. I would like to understand, however, why the second variant works and the first one doesn't?
The second variant works because Scala refines its types parameter-block by parameter-block. If you don't specify the type of your input parameter for the function, it's possible that it would change the type T that it has inferred based on the first parameter. If you push it to a separate parameter block, Scala's already decided what T must be by the time it hits that block, so it fills in the only possible value for the function argument type.

What's the difference between multiple parameters lists and multiple parameters per list in Scala?

In Scala one can write (curried?) functions like this
def curriedFunc(arg1: Int) (arg2: String) = { ... }
What is the difference between the above curriedFunc function definition with two parameters lists and functions with multiple parameters in a single parameter list:
def curriedFunc(arg1: Int, arg2: String) = { ... }
From a mathematical point of view this is (curriedFunc(x))(y) and curriedFunc(x,y) but I can write def sum(x) (y) = x + y and the same will be def sum2(x, y) = x + y
I know only one difference - this is partially applied functions. But both ways are equivalent for me.
Are there any other differences?
Strictly speaking, this is not a curried function, but a method with multiple argument lists, although admittedly it looks like a function.
As you said, the multiple arguments lists allow the method to be used in the place of a partially applied function. (Sorry for the generally silly examples I use)
object NonCurr {
def tabulate[A](n: Int, fun: Int => A) = IndexedSeq.tabulate(n)(fun)
}
NonCurr.tabulate[Double](10, _) // not possible
val x = IndexedSeq.tabulate[Double](10) _ // possible. x is Function1 now
x(math.exp(_)) // complete the application
Another benefit is that you can use curly braces instead of parenthesis which looks nice if the second argument list consists of a single function, or thunk. E.g.
NonCurr.tabulate(10, { i => val j = util.Random.nextInt(i + 1); i - i % 2 })
versus
IndexedSeq.tabulate(10) { i =>
val j = util.Random.nextInt(i + 1)
i - i % 2
}
Or for the thunk:
IndexedSeq.fill(10) {
println("debug: operating the random number generator")
util.Random.nextInt(99)
}
Another advantage is, you can refer to arguments of a previous argument list for defining default argument values (although you could also say it's a disadvantage that you cannot do that in single list :)
// again I'm not very creative with the example, so forgive me
def doSomething(f: java.io.File)(modDate: Long = f.lastModified) = ???
Finally, there are three other application in an answer to related post Why does Scala provide both multiple parameters lists and multiple parameters per list? . I will just copy them here, but the credit goes to Knut Arne Vedaa, Kevin Wright, and extempore.
First: you can have multiple var args:
def foo(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
...which would not be possible in a single argument list.
Second, it aids the type inference:
def foo[T](a: T, b: T)(op: (T,T) => T) = op(a, b)
foo(1, 2){_ + _} // compiler can infer the type of the op function
def foo2[T](a: T, b: T, op: (T,T) => T) = op(a, b)
foo2(1, 2, _ + _) // compiler too stupid, unfortunately
And last, this is the only way you can have implicit and non implicit args, as implicit is a modifier for a whole argument list:
def gaga [A](x: A)(implicit mf: Manifest[A]) = ??? // ok
def gaga2[A](x: A, implicit mf: Manifest[A]) = ??? // not possible
There's another difference that was not covered by 0__'s excellent answer: default parameters. A parameter from one parameter list can be used when computing the default in another parameter list, but not in the same one.
For example:
def f(x: Int, y: Int = x * 2) = x + y // not valid
def g(x: Int)(y: Int = x * 2) = x + y // valid
That's the whole point, is that the curried and uncurried forms are equivalent! As others have pointed out, one or the other form can be syntactically more convenient to work with depending on the situation, and that is the only reason to prefer one over the other.
It's important to understand that even if Scala didn't have special syntax for declaring curried functions, you could still construct them; this is just a mathematical inevitability once you have the ability to create functions which return functions.
To demonstrate this, imagine that the def foo(a)(b)(c) = {...} syntax didn't exist. Then you could still achieve the exact same thing like so: def foo(a) = (b) => (c) => {...}.
Like many features in Scala, this is just a syntactic convenience for doing something that would be possible anyway, but with slightly more verbosity.
The two forms are isomorphic. The main difference is that curried functions are easier to apply partially, while non-curried functions have slightly nicer syntax, at least in Scala.