0

I am new to Scala (Functional Programming). I am reading the book 'Functional Programming in Scala'. It was an exercise in which we need to define a partially applied function

def partial1 [A, B, C] (a: A, f: (A, B) => C): B => C = {
    (b: B) => f(a, b)
}

I was wondering what is a real world use of this function? I tried to read different blogs to find an example, but couldn't find a useful example.

Varun Risbud
  • 143
  • 9
  • The link:http://blog.bruchez.name/2011/10/scala-partial-functions-without-phd.html gives a good real-world example of how partial functions are used in Scala. – jrook Apr 04 '17 at 04:47
  • 1
    it's not PartialFunction, it's partially-applied function! – dk14 Apr 04 '17 at 04:48
  • @dk14, they are actually two different things. PartialFunction is a type in Scala. see the link in my comment. – jrook Apr 04 '17 at 04:54
  • These SO questions are also worth looking at for better understanding of partial functions:http://stackoverflow.com/questions/32085060/partial-functions-in-scala and http://stackoverflow.com/questions/8650549/using-partial-functions-in-scala-how-does-it-work – jrook Apr 04 '17 at 05:03
  • 1
    @jrook I know what PartialFunction is. What I'm saying is that `def partial1` in OP's question isn't `PartialFunction` at all. The point of that exercise was to demonstrate a complex case of partial application - it's not related to Partial/Total functions in **any way**! – dk14 Apr 04 '17 at 05:30
  • 2
    @jrook OP just confused two completely different things with similar names. – dk14 Apr 04 '17 at 05:31
  • Your question is unclear. What partial function are you talking about? The only function in your code is `(b: B) => f(a, b)`? How do you know it is partial? This function is partial, IFF `f` is partial, which you can't know, because it is a parameter. – Jörg W Mittag Apr 04 '17 at 08:42
  • @dk14 thanks for pointing out that it's a partially applied function. As I said I am new to FP, hence the confusion. I have edited the question to indicate that it's a partially applied function in Scala. – Varun Risbud Apr 04 '17 at 13:57

1 Answers1

2

(Relevant to your question before you edited it) Let's start with terminology. PartialFunction is trait in scala that says that your function might not process all possible variations of the input:

val partialFunction: PartialFunction[Int, Int] = {
  case 1 => 1
  case 2 => 2
}

scala> partialFunction(1)
res43: Int = 1

scala> partialFunction(3)
scala.MatchError: 3 (of class java.lang.Integer)

It's completely unrelated to your example, which is a partial application - the article provided basically shows real-world example with email filtering.


About partial application.

Sometimes you might have a function with several parameters, let's say:

def sendMail(recipient: String, subject: String, body: String) = println(s"To: $recipient\n Subj: $subject\n Body: $body")

This function might be a part of the API, so you might not be able to change it. Now, let's say you need to send a same email to many different recipients:

object Spam{
  val subject = "Hello!"
  val body = "World!"
  def spam(recipient: String) = sendMail(recipient, subject, body)
}

scala> Spam.spam("aaa@aa")
 To: aaa@aa
 Subj: Hello!
 Body: World!

Another way to do that is to generate a function per subject/body, so to make it customizable:

def spammer(subject: String, body: String): String => Unit = (recipient: String) => {
  sendMail(recipient, subject, body)
}

val spam1 = spammer("Hello", "World!")
spam1("emai@email.com")

It's roughly equivalent to OOP's:

 class Spammer(subject: String, body: String){
    def apply(recipient: String) = sendMail(recipient, subject, body)
 }

 val spam1 = new Spammer("Hello", "World!")
 spam1("emai@email.com")

The difference is that partial application is able to deal more easily with complex cases and also has additional syntax sugar:

 val spam1 = sendMail(_, "Hello", "World!")
 spam1("emai@email.com")

So in simple cases you don't even need to define your own wrapper.


Returning to your more sophisticated example, you could use it this way:

scala> val incrementInt = partial1[Int, Int, Int](1, _ + _)
incrementInt: Int => Int = $$Lambda$1258/21635151@18ca65ea

scala> incrementInt(2)
res47: Int = 3

scala> val incrementList = partial1[List[Int], List[Int], List[Int]](List(0), _ ++ _)
incrementList: List[Int] => List[Int] = $$Lambda$1258/21635151@79f8af90

scala> incrementList(List(0))
res49: List[Int] = List(0, 0)

scala> incrementList(List(0, 0))
res50: List[Int] = List(0, 0, 0)

Basically abstract over addition (A, B) = C of some fixed abstract element A to unknown element B. In the example above it's addition over integers, and addition over lists of zeros. You can imagine more practical example like merging two json's with some fixed pattern and so on.

You might think of partail1 as providing a unified interface to all those cases.

dk14
  • 22,206
  • 4
  • 51
  • 88