spiffman spiffman - 1 month ago 17
Scala Question

Keeping named and default parameters when assigning a function

When assigning a function using an unapplied method, it appears that named and default parameters are lost. Is there any way to avoid this?

def foo(namedParam: String = "defaultValue") = namedParam*2
// scala> foo()
// res8: String = defaultValuedefaultValue

def bar = foo _
// scala> bar()
// <console>:28: error: not enough arguments for method
// apply: (v1: String)String in trait Function1.
// Unspecified value parameter v1.


The reason I want to do this is to bundle my imports in a single file, i.e.

myproject/imports.scala

object imports {
def externalAPIFunction = myproject.somepackage.internalFunction _
}


scala shell

import myproject.imports._

externalAPIFunction() // no named or default arguments :(


Any way to do this or do I have to put my default arguments in the external function definition?

Answer

Functions (i.e. values of type Function<N>[...]) simply can't have default or implicit parameters in Scala, only methods can. And method _ returns a function: that's what it's for. So yes, to achieve your purpose you'd need to write

object imports {
  def externalAPIFunction(namedParam: String = "defaultValue") = 
    myproject.somepackage.internalFunction(namedParam)
}

You can avoid duplication using

object imports {
  val x = myproject.somepackage
}

// elsewhere
import myproject.imports._

x.internalAPIFunction()

// or
import myproject.imports.x._

internalAPIFunction()

which may or may not be good enough for your purposes.