简体   繁体   中英

Scala function partial application

I'm trying to understand how function partial application works in Scala.

To do that, I've built this simple code:

object Test extends App {
  myCustomConcat("General", "Public", "License") foreach print

  GeneralPublicLicenceAcronym(myCustomConcat(_)) foreach print

  def myCustomConcat(strings: String*): List[Char] = {
    val result = for (s <- strings) yield {
      s.charAt(0)
    }

    result.toList
  }


  def GeneralPublicLicenceAcronym (concatFunction: (String*) => List[Char] ) = {

    myCustomConcat("General", "Public", "License")
  }
}

myCostumConcat function takes in input an array of String and it returns a list containing the first letter of each string.

So, the code

myCustomConcat("General", "Public", "License") foreach print

will print on console: GPL

Suppose now that I want to write a function to generate the GPL acronym, using (as input parameter) my previous function extracting the first letter of each string:

def GeneralPublicLicenceAcronym (concatFunction: (String*) => List[Char] ): List[Char] = {

    myCustomConcat("General", "Public", "License")
  }

Running this new function with partial application:

GeneralPublicLicenceAcronym(myCustomConcat(_)) foreach print

I get this error:

Error:(8, 46) type mismatch; found : Seq[String] required: String GeneralPublicLicenceAcronym(myCustomConcat(_)) foreach print

Why? Can I use partial application in this case?

All you need to do is change myCustomConcat(_) to myCustomConcat _ , or indeed just myCustomConcat

What you are doing isn't exactly partial application - it's just using a method as a function value.

In some cases (where a function value is expected) the compiler will work out what you mean, but in other contexts you often need to tell the compiler your intention, using the _ suffix.

"partial application" means that we are supplying some, but not all, of the arguments to a function, to create a new function, for example:

  def add(x: Int, y: Int) = x + y           //> add: (x: Int, y: Int)Int

  val addOne: Int => Int = add(1, _)        //> addOne  : Int => Int = <function1>

  addOne(2)                                 //> res0: Int = 3

I suppose your case could be seen as partial application, but applying none of the arguments - you can use partial application syntax here, but you need to give a _* hint to the compiler because of the repeated parameters ( String* ), which ends up a bit ugly:

myCustomConcat(_:_*)

See also: Scala type ascription for varargs using _* cause error

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM