Partiality *

Controversial? Perhaps; Opinionated? Certainly.

Partially Applied Function vs. Partial Function

They are two different pairs of shoes. One is about application and the other is an inherent property of the definition.
Partial application or a partially applied function, is a function that is in the middle of being applied to its parameters and hence in some form incomplete. A partial function on the other hand is a a function that is not total i.e partial. What's a total function? We go into the details below.
### Partially Applied Function (or Partial Application) {#partial-application}

Let us say you have a curried function `add` defined as below in Scala REPL

scala> val add : Int => Int => Int  =  a => b => a + b
add: Int => (Int => Int)

and Haskell REPL

Prelude> let add a b = a + b   

Then you can partially and completely apply `add` like
scala> val plus1 = add(1) //partial application, we provide just one of the two params
plus1: Int => Int = < function1 >

scala> val v = plus1(2)  //the partially applied function has been completely applied
v: Int = 3

Prelude> let plus1 = add 1     //partial application

Prelude> plus1 2

Note partially applied functions are themselves function values as evidenced by `plus1: Int => Int = < function1 >` above. A function has been completely applied when it delivers an end result that itself can not be further applied to a value. 
scala> val add: Int => Int => Int => Int = a => b => c => a + b + c

scala> val plus1 = add(1) 

scala> val plus12 = plus1(2)

scala> val complete = plus12(3)
complete: Int = 6

### Partial Function {#partial-function}

If you like precise definitions: 

"In mathematics, a partial function from X to Y (written as f: X ↛ Y) is a function f: X' → Y, for some subset X' of X. It generalizes the concept of a function f: X → Y by not forcing f to map every element of X to an element of Y (only some subset X' of X). If X' = X, then f is called a total function and is equivalent to a function."[^wikipart]

[^wikipart]: [Wikipedia: Partial Function](

Even though the above definition is in terms of sets and not types it captures the essence. 

How about an example?

We can define division of integers[^integers] as follows

[^integers]: We ignore integer overflow and don't use Double as division by 0.0 yields infinity.

scala> val div: Int => Int => Int = a => b => a / b 
div: Int => (Int => Int) = < function1 >

scala> div(4)(2)
res2: Int = 2

scala> div(1)(0)
java.lang.ArithmeticException: / by zero
  at $anonfun$1$$anonfun$apply$1.apply$mcDI$sp(:7)
  ... 32 elided


So division for `Int`s is undefined when the divisor is `0`. Another example is the `head` of a `List` that is empty. 

There is a very simple way to turn partial functions into total functions by mapping the result to a sum type like `Option` or `Either`. 

To make `div` total we can redefine it. Instead of the following 
Int => Int => Int

we declare it to be  

Int => Int => Option[Int]

Here is a Scala REPL session that shows this.

scala> val div: Int => Int => Option[Int] = a => b => if(b != 0) { Some(a / b) } else { None }
div: Int => (Int => Option[Int]) = < function1 >

scala> div(4)(2)
res17: Option[Int] = Some(2)

scala> div(1)(0)
res18: Option[Int] = None

That is why `List` has the method `headOption`.

Some might argue that Scala only has partial functions, as any function might throw an exception at any time or return `null`/ `Nothing`. And that one should explicitly signal totality using return types like `Option`, `Either` or even a `List`. 

Scala also has the `PartialFunction` trait that allows querying if a function is defined for a value, acts as a backbone for the pattern matching machinery, allows chaining of fall-backs and allows `lift`ing its value into an `Option` hence mimicking a total function. Let us see the `PartialFunction` in action 

//let us type alias partial function to the mathematical operator seen in the definition above 
scala> type ↛[-A, +B] = PartialFunction[A, B] 
defined type alias $u219B

//if utf is a pain then here is an alternative
scala> type =/>[-A, +B] = PartialFunction[A, B]
defined type alias $eq$div$greater

// well we need to cheat a bit as math.log produces values also for 0 and negative numbers
scala> object NotDefined extends Exception with util.control.NoStackTrace 

//Note: there are better alternatives than doing what we do 
//so don't treat it as an example to repeat in your production code
//raising and catching exceptions is bad
scala> val log : Double =/> Double = new PartialFunction[Double, Double] { 
          def isDefinedAt(d: Double) = d > 0.0    //guard method
          def apply(d: Double) = if(d > 0.0) math.log(d) else throw NotDefined 
log: =/>[Double,Double] = < function1 >       
scala> log(2)
res6: Double = 0.6931471805599453

scala> log.isDefinedAt(0)
res7: Boolean = false

scala> log(0)

scala> log.lift(0)          //make things total
res8: Option[Double] = None

scala> val nan: Double =/> Double = {case _ => Double.NaN}   //pattern matching!
nan: =/>[Double,Double] = < function1 >

scala> (log orElse nan)(0)     // nan is our fallback we could chain more if needed
res9: Double = NaN


That was a very quick tour of the `PartialFunction` trait. 

### Bonus: Partial Type Application {#partial-type-application}

Just as a function may be partially applied to yield an intermediate function literal so a type constructor may be partially applied (bound) to yield a partially applied type. Here is how we can bound the left type of `Either`.  

type EitherLeftString[A] = Either[String, A]

That defines a type alias with a very descriptive name. We can complete the type to get a proper type 

type Complete = EitherLeftString[Int]

Now would be a great place to talk about type lambdas. Perhaps later :)