parameter list (“*”) with lazy “by-name” parameters?

I can:

scala> def foo( f: => String) = println(f)
foo: (f: => String)Unit

and I can:

scala> def foo( f: String*) = f.map(println)
foo: (f: String*)Seq[Unit]

but I can't:

scala> def foo( f: =>String* ) = f.map(println)
<console>:1: error: ')' expected but identifier found.
       def foo( f: =>String* ) = f.map(println)
                       ^

nor

scala> def foo( f: (=>String)* ) = f.map(println)
<console>:1: error: no by-name parameter type allowed here
       def foo( f: (=>String)* ) = f.map(println)
                ^

Is there some other way to do what I want? Why isn't this allowed?

Answers


Here the => means that the parameter is passed by name. What you have tried isn't allowed simply because =>String is not an actual type (as opposed to say ()=>String) and you cannot make an Array[=>String]. Given that a variadic parameter x: T* is under the hood handled as an array containing all the parameter's values (as in x: Array[T]), this is the reason why not being able to create a Array[=>String] (which does not make sense) also means that a variadic parameter f: (=>String)* is not possible.

This problem can be worked around using a little wrapper class:

implicit class ByName[T]( getValue: => T ) extends Proxy {
  def apply(): T = getValue
  def self = apply()
}

Then change the signature of your method like so:

def foo( fs: ByName[String]* )

When calling your method with multiple arguments, all the arguments will be implicitly wrapped into a ByName instance, and then you can call apply to get the actal value:

def foo( fs: ByName[String]* ) = fs foreach { f => println( f() ) }

Given that ByName extends Proxy for simple things such as calling toString or testing equality you don't even have to call apply. Thus you can simply do:

def foo( fs: ByName[String]* ) = f foreach println

Need Your Help

Standards for output of programs running through a console window?

text cmd console-application

Is there a standard set for the number of rows and columns (width and height) that are displayed in a standard console window?

the average of optical flow

c++ image-processing opencv

I want to find the average of the optical flow, I could extract the features from the first frame and found their location in the next frame. Now, I want to find the average of the displacement in ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.