# What's the use case of this kind of function?

``````scala> def mytest(s:String)(f:String=>Int) = f(s)
def mytest(s: String)(f: String => Int): Int

scala> val test2 = mytest("building") _
val test2: (String => Int) => Int = \$Lambda\$1106/0x00000008010c7350@71687d8f
``````

what use case will test2 be used for?
is this a partial function?

Thanks

This article covers what you are looking at Partially-Applied Functions (and Currying) in Scala | alvinalexander.com. In this case `test2` os a partially applied function.

Usually this is just for syntactic reasons (in my experience).

Consider the following

``````val in = List(6,5,4,3,2,1,2,3,4,5,6)
def isFactorOf(n: number)(maybeFactor: number): boolean = ???

val isFactorOfLast = isFactorOf(in.last)

in
.filter(isFactorOfFirst)
.map(x => x*x)
.filter(isFactorOfLast)
``````

This could also be written like this

``````val in = List(6,5,4,3,2,1,2,3,4,5,6)
def isFactorOf(n: number)(maybeFactor: number): boolean = ???

val last = in.last

in
.filter(isFactorOf(first))
.map(x => x*x)
.filter(isFactorOf(last))
``````

Or

``````val in = List(6,5,4,3,2,1,2,3,4,5,6)
def isFactorOf(n: number, maybeFactor: number): boolean = ???

val last = in.last

in
.filter(isFactorOf(first, _))
.map(x => x*x)
.filter(isFactorOf(last, _))
``````

(there are probably a miriad of other ways to write this).

In scala 2 currying is also used to help the compiler with type inference IIRC.

Consider this trivial scastie, the uncurried variant doesn’t infer the types correctly at the callsite (this is fixed in scala 3). Scastie - An interactive playground for Scala.

It will be interesting to see what others make of currying and partially applied functions though

2 Likes

is " Partially-applied functions" the same as “partial functions”? thank you.

No a partial function is a function that is potentially non complete in terms of handling all of it’s inputs. Here is a good article explaining it
https://alvinalexander.com/scala/how-to-define-use-partial-functions-in-scala-syntax-examples/

for example

``````// this partial function doesn't work for odd inputs
val partial: PartialFunction[Int, Int] = {
case d if d % 2 == 0 => d
}

// we can then use it like so, odd numbers will always return -1
partial.applyOrElse(1, d => -1)
``````
2 Likes

Another way of describing a “partial function” is to contrast it with its “opposite”, a “total function”.

Total Function:
A “total function” asserts the entire input range results in an output existing within the defined domain.

``````def isEven(value: Int): Boolean =
value % 2 == 0
``````

There is literally no value you can pass to `isEven` that will result in an “undefined” behavior. Every valid `Int` will definitively and correctly return either `true` or `false`.

Partial Function:
A “partial function” asserts some parts of the input range will result in an output existing within the domain, and the excluded parts of the input range will result in an output of “undefined” (which by default likely results in a RuntimeException).

``````def pfSquareRootFloor(value: Int): Int = {
assert(value > -1, s"value[\$value] must be greater than -1")
//implementation omitted for brevity, but included at the Scastie Link
}

for (v <- 0 to 36)
println(s"\$v: \${pfSquareRootFloor(v)}")
println("Finished!")
``````

The `pfSquareRootFloor` function will throw a runtime `AssertionError` if passed a negative `Int`.

Translating a Partial Function into a Total Function:
To avoid “undefined” (and the runtime `AssertionError`), a “partial function” can be “wrapped” to produce a “total function”. This is also referred to as “lifting”, as in the partial function is “lifted” to a “total function”.

There are two approaches.

1. Literally wrap the partial function with something that makes it a total function.
``````import scala.util.Try

def pfSquareRootFloor(value: Int): Int = {
assert(value > -1, s"value[\$value] must be greater than -1")
//implementation omitted for brevity, but included at the Scastie Link
}

for (v <- -1 to 36)
println(s"\$v: \${Try(pfSquareRootFloor(v))}")
println("Finished!")
``````

1. If you have access to modify the implementation, then the second approach is to design the function to be total which can then is clearly communicated by the type signature.

Here’s a solution based on `Option`:

``````def fSquareRoot(value: Int): Option[Int] = {
if (value > -1)
Some(
//implementation omitted for brevity, but included at the Scastie Link
)
else
None
}

for (v <- -1 to 36)
println(s"\$v: \${fSquareRootFloor(v)}")
println("Finished!")
``````

And here’s a solution based on `Either`:

``````def fSquareRootFloor(value: Int): Either[String, Int] = {
if (value > -1)
Right(
//implementation omitted for brevity, but included at the Scastie Link
)
else
Left(s"value[\$value] must be greater than -1")
}

for (v <- -1 to 36)
println(s"\$v: \${fSquareRootFloor(v)}")
println("Finished!")
``````