2017-04-04 66 views
0

我是Scala(函數式編程)的新手。我正在閱讀「Scala中的函數式編程」一書。這是我們需要定義一個部分應用功能什麼是Scala的部分應用功能的真實世界示例

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

我想知道什麼是真正的世界中使用此功能的鍛鍊?我嘗試閱讀不同的博客來查找示例,但找不到有用的示例。

+0

鏈接:http://blog.bruchez.name/2011/10/scala-partial-functions-without-phd.html給出了Scala中如何使用部分函數的一個很好的實例。 – jrook

+1

它不是PartialFunction,它是部分應用的函數! – dk14

+0

@ dk14,它們實際上是兩個不同的東西。 PartialFunction是Scala中的一種類型。請參閱我評論中的鏈接。 – jrook

回答

2

(與編輯之前的問題相關)讓我們從術語開始。 PartialFunction是Scala trait,指出你的功能可能無法處理輸入的所有可能的變化:

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) 

這是完全無關的例子,這是一個partial application - 與電子郵件基本上提供的文章顯示真實世界的例子過濾。


關於部分申請。

有時候你可能有幾個參數的功能,比方說:

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

此功能可能是API的一部分,所以你可能無法改變它。現在,讓我們說你需要發送相同的電子郵件到許多不同的收件人:

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

scala> Spam.spam("[email protected]") 
To: [email protected] 
Subj: Hello! 
Body: World! 

另一種方法是生成每科/體內的功能,所以使它可定製:

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

val spam1 = spammer("Hello", "World!") 
spam1("[email protected]") 

這大致相當於OOP的:

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

val spam1 = new Spammer("Hello", "World!") 
spam1("[email protected]") 

不同的是,部分應用程序能夠與複雜的案件處理更輕鬆,也有額外的語法糖:

val spam1 = sendMail(_, "Hello", "World!") 
spam1("[email protected]") 

因此,在簡單情況下,您甚至不需要定義自己的包裝。


回到你的更復雜的例子,你可以使用這種方式:

scala> val incrementInt = partial1[Int, Int, Int](1, _ + _) 
incrementInt: Int => Int = $$Lambda$1258/[email protected] 

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/[email protected] 

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

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

在一些固定的抽象元素A的除了(A, B) = C未知元素B基本上抽象。在上面的例子中,它是對整數的加法,以及在零列表上的加法。你可以想象更實際的例子,比如將兩個json與某些固定模式合併等等。

您可能會認爲partail1爲所有這些情況提供了統一接口。