欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解Scala函數(shù)式編程過(guò)程

 更新時(shí)間:2017年10月10日 16:02:04   作者:牧師-Panda  
這篇文章主要介紹了深入理解Scala函數(shù)式編程過(guò)程的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下

深入理解Scala函數(shù)式編程過(guò)程

我們馬上開(kāi)始一段變態(tài)的過(guò)程

如果要求立方和,可以這么做

35 * 35 * 35 
68 * 68 * 68 

沒(méi)毛病,抽象一點(diǎn)兒,寫個(gè)函數(shù):

def cube(n: Int) = n * n * n 
cube(35) 
cube(68)

省事兒了,如果求1到10的立方和,OK,寫個(gè)遞歸

def cube(n: Int) = n * n * n 
 def sumCube(a: Int, b: Int): Int = 
   if (a > b) 0 else cube(a) + sumCube(a + 1, b) 
 
sumCube(1, 10)

變態(tài)一點(diǎn)兒,立方和,平方和,階乘和,依舊寫出它們的函數(shù)并且依次計(jì)算沒(méi)毛病

def cube(n: Int) = n * n * n 
def id(n: Int) = n 
def square(n : Int) = n * n 
def fact(n: Int): Int = 
  if (n == 0) 1 else n * fact(n - 1) 
 
def sumCube(a: Int, b: Int): Int = 
  if (a > b) 0 else cube(a) + sumCube(a + 1, b) 
 
def sumSquare(a: Int, b: Int): Int = 
  if(a > b) 0 else square(a) + sumSquare(a + 1, b) 
  
def sumFact(a: Int, b: Int): Int = 
  if (a > b) 0 else fact(a) + sumFact(a + 1, b) 
 
def sumInt(a: Int, b: Int): Int = 
  if(a > b) 0 else id(a) + sumInt(a + 1, b)  
 
 sumCube(1, 10) 
 sumInt(1, 10) 
 sumSquare(1, 10) 
 sumFact(1, 10)

然后你發(fā)現(xiàn),你已經(jīng)寫了一堆同樣邏輯的if else,看起來(lái)不奇怪么,這種無(wú)腦的操作當(dāng)然要避免:

我們要把這些函數(shù)名不同但是處理邏輯相同的渣渣都封裝到一個(gè)函數(shù)中,并且這個(gè)函數(shù)將作為參數(shù)賦值到高階函數(shù)中,運(yùn)行的結(jié)果只跟傳入的參數(shù)類型有關(guān)系,也就是把cube,square,fact,泛化成一個(gè)f

def cube(n: Int) = n * n * n 
def id(n: Int) = n 
def square(n : Int) = n * n 
def fact(n: Int): Int = 
  if (n == 0) 1 else n * fact(n - 1) 
//高階函數(shù)
def sum(f: Int=>Int, a:Int, b:Int): Int = 
  if(a>b) 0 else f(a)+sum(f, a+1, b)
// 使用高階函數(shù)重新定義求和函數(shù)
def sumCube(a: Int, b: Int): Int = sum(cube, a, b) 
def sumSquare(a: Int, b: Int): Int = sum(square, a, b) 
def sumFact(a: Int, b: Int): Int = sum(fact, a, b) 
def sumInt(a: Int, b: Int): Int = sum(id, a, b) 
 
 sumCube(1, 10) 
 sumInt(1, 10) 
 sumSquare(1, 10) 
 sumFact(1, 10)

但是這樣寫,還有個(gè)問(wèn)題,就是前面定義了一堆cube,id的初始定義,后面還要繼續(xù)定義,實(shí)際上就是套了一層包裝,不要了,去掉,使用匿名函數(shù)的功能來(lái)將調(diào)用進(jìn)一步簡(jiǎn)化。多數(shù)情況下,我們關(guān)心的是高階函數(shù),而不是作為參數(shù)傳入的函數(shù),所以為其單獨(dú)定義一個(gè)函數(shù)是沒(méi)有必要的。值得稱贊的是 Scala 中定義匿名函數(shù)的語(yǔ)法很簡(jiǎn)單,箭頭左邊是參數(shù)列表,右邊是函數(shù)體,參數(shù)的類型是可省略的,Scala 的類型推測(cè)系統(tǒng)會(huì)推測(cè)出參數(shù)的類型。使用匿名函數(shù)后,我們的代碼變得更簡(jiǎn)潔了:

//保留邏輯較為復(fù)雜的函數(shù)
def fact(n: Int): Int = 
if (n == 0) 1 else n * fact(n - 1) 
 
def sum(f: Int => Int, a: Int, b: Int): Int = 
  if (a > b) 0 else f(a) + sum(f, a + 1, b) 
 
// 使用高階函數(shù)重新定義求和函數(shù)
def sumCube(a: Int, b: Int): Int = sum(x => x * x * x, a, b) 
def sumSquare(a: Int, b: Int): Int = sum(x => x * x, a, b) 
def sumFact(a: Int, b: Int): Int = sum(fact, a, b) 
def sumInt(a: Int, b: Int): Int = sum(x => x, a, b) 
 

sumCube(1, 10) 
sumInt(1, 10) 
sumSquare(1, 10) 
sumFact(1, 10)

寫到這里問(wèn)題解決的差不多了,但是我們仔細(xì)想想,函數(shù)式編程的真諦,一個(gè)輸入到另一個(gè)輸出,而不是像這樣兩個(gè)參數(shù)傳來(lái)傳去,看起來(lái)很麻煩,于是乎

def fact(n: Int): Int = 
if (n == 0) 1 else n * fact(n - 1) 
 
// 高階函數(shù)
def sum(f: Int => Int): (Int, Int) => Int = { 
  def sumF(a: Int, b: Int): Int = 
   if (a > b) 0 else f(a) + sumF(a + 1, b) 
 
  sumF 
} 
// 使用高階函數(shù)重新定義求和函數(shù)
def sumCube: Int = sum(x => x * x * x) 
def sumSquare: Int = sum(x => x * x) 
def sumFact: Int = sum(fact) 
def sumInt: Int = sum(x => x) 
 
// 這些函數(shù)使用起來(lái)還和原來(lái)一樣 ! 
sumCube(1, 10) 
sumInt(1, 10) 
sumSquare(1, 10) 
sumFact(1, 10)

實(shí)際上這個(gè)時(shí)候sum里面?zhèn)魅氲囊呀?jīng)是匿名函數(shù)了,類似于g(f(x))里面的f(x), 你還需要去調(diào)用那個(gè)f(x)而不是去腦補(bǔ)運(yùn)算.

我們?cè)賮?lái)開(kāi)一下腦洞,既然sum返回的是一個(gè)函數(shù),我們可以直接使用這些函數(shù),沒(méi)有必要再重復(fù)寫一遍調(diào)用命令了,sumCube(1, 10) 類的語(yǔ)句可以省去不要了。

def fact(n: Int): Int = 
  if (n == 0) 1 else n * fact(n - 1) 
 
// 高階函數(shù)
def sum(f: Int => Int): (Int, Int) => Int = { 
  def sumF(a: Int, b: Int): Int = 
   if (a > b) 0 else f(a) + sumF(a + 1, b) 
  sumF 
}

// 直接調(diào)用高階函數(shù) ! 
sum(x => x * x * x) (1, 10) //=> sumCube(1, 10) 
sum(x => x) (1, 10)      //=> sumInt(1, 10) 
sum(x => x * x) (1, 10)   //=> sumSquare(1, 10) 
sum(fact) (1, 10)       //=> sumFact(1, 10)

最后我們還可以使用高階函數(shù)的語(yǔ)法糖來(lái)進(jìn)一步優(yōu)化這段代碼: 

// 沒(méi)使用語(yǔ)法糖的 sum 函數(shù)
 def sum(f: Int => Int): (Int, Int): Int = { 
 def sumF(a: Int, b: Int): Int = 
  if (a > b) 0 else f(a) + sumF(a + 1, b) 
 
 sumF 
} 
// 使用語(yǔ)法糖后的 sum 函數(shù)
 def sum(f: Int => Int)(a: Int, b: Int): Int = 
 if (a > b) 0 else f(a) + sum(f)(a + 1, b)

我反而覺(jué)得用語(yǔ)法糖更容易理解一點(diǎn),更傾向于我們學(xué)的數(shù)學(xué)語(yǔ)言。

讀者可能會(huì)問(wèn):我們把原來(lái)的sum函數(shù)轉(zhuǎn)化成這樣的形式,好處在哪里?答案是我們獲得了更多的可能性,比如剛開(kāi)始求和的上下限還沒(méi)確定,我們可以在程序中把一個(gè)函數(shù)傳給sum, sum(fact)完全是一個(gè)合法的表達(dá)式,待后續(xù)上下限確定下來(lái)時(shí),再把另外兩個(gè)參數(shù)傳進(jìn)來(lái)。對(duì)于 sum 函數(shù),我們還可以更進(jìn)一步,把 a,b 參數(shù)再轉(zhuǎn)化一下,這樣 sum 函數(shù)就變成了這樣一個(gè)函數(shù):它每次只能接收一個(gè)參數(shù),然后返回另一個(gè)接收一個(gè)參數(shù)的函數(shù),調(diào)用后,又返回一個(gè)只接收一個(gè)參數(shù)的函數(shù)。這就是傳說(shuō)中的柯里化,多么完美的形式!在現(xiàn)實(shí)世界中,的確有這樣一門函數(shù)式編程語(yǔ)言,那就是 Haskell,在 Haskell 中,所有的函數(shù)都是柯里化的,即所有的函數(shù)只接收一個(gè)參數(shù)!

// 柯里化后的 sum 函數(shù)
 def sum(f: Int => Int)(a: Int) (b: Int): Int = 
if (a > b) 0 else f(a) + sum(f)(a + 1)(b) 
 
// 使用柯里化后的高階函數(shù) ! 
 sum(x => x * x * x)(1)(10) //=> sumCube(1, 10) 
 sum(x => x)(1)(10)      //=> sumInt(1, 10)
 

如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • vant/vue實(shí)現(xiàn)小程序下拉刷新功能方法詳解

    vant/vue實(shí)現(xiàn)小程序下拉刷新功能方法詳解

    這篇文章主要介紹了vant/vue實(shí)現(xiàn)小程序下拉刷新功能方法詳解,需要的朋友可以參考下
    2022-12-12
  • Hbuilder連遠(yuǎn)程接服務(wù)器上傳代碼的圖文教程

    Hbuilder連遠(yuǎn)程接服務(wù)器上傳代碼的圖文教程

    下面小編就為大家分享一篇Hbuilder連遠(yuǎn)程接服務(wù)器上傳代碼的圖文教程,具有很好的參考價(jià)值,一起跟隨小編過(guò)來(lái)看看吧,希望對(duì)大家有所幫助
    2017-11-11
  • 在Visual Studio 中使用git及Git概念

    在Visual Studio 中使用git及Git概念

    Git是一個(gè)開(kāi)源的分布式版本控制系統(tǒng),可以有效、高速的處理從很小到非常大的項(xiàng)目版本管理,是目前使用范圍最廣的版本管理工具,本文重點(diǎn)給大家介紹在Visual Studio 中使用git及git的工作原理,感興趣的朋友一起看看吧
    2021-04-04
  • Scala函數(shù)式編程專題--scala集合和函數(shù)

    Scala函數(shù)式編程專題--scala集合和函數(shù)

    這篇文章主要介紹了scala集合和函數(shù)的的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • H5混合開(kāi)發(fā)手機(jī)Web App入門:概念篇

    H5混合開(kāi)發(fā)手機(jī)Web App入門:概念篇

    如果你開(kāi)始學(xué)習(xí)手機(jī) App 開(kāi)發(fā),就一定會(huì)聽(tīng)到 H5 這個(gè)詞。它是目前的主流開(kāi)發(fā)技術(shù)之一,容易上手,開(kāi)發(fā)周期短、成本低、兼容傳統(tǒng) Web 開(kāi)發(fā)。但是,很少有文章詳細(xì)介紹,H5 到底是什么技術(shù),有什么原理,跟其他技術(shù)的差異在哪里。
    2022-12-12
  • 人人都是開(kāi)發(fā)者:7款傻瓜式APP開(kāi)發(fā)工具

    人人都是開(kāi)發(fā)者:7款傻瓜式APP開(kāi)發(fā)工具

    國(guó)外的營(yíng)銷工作者和技術(shù)開(kāi)發(fā)者開(kāi)發(fā)了許多能幫助企業(yè)創(chuàng)建簡(jiǎn)單APP應(yīng)用的工具,通過(guò)這些工具,就算是一個(gè)對(duì)程序一竅不通的普通網(wǎng)民都可以很容易的創(chuàng)建一個(gè)企業(yè)的APP程序,并可以對(duì)程序進(jìn)行應(yīng)用更新維護(hù),開(kāi)展?fàn)I銷等活動(dòng)
    2013-11-11
  • 計(jì)算機(jī)網(wǎng)絡(luò)編程MQTT協(xié)議基礎(chǔ)原理詳解

    計(jì)算機(jī)網(wǎng)絡(luò)編程MQTT協(xié)議基礎(chǔ)原理詳解

    這篇文章主要為大家介紹了計(jì)算機(jī)編程MQTT協(xié)議的基礎(chǔ)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11
  • 好玩又實(shí)用的查看函數(shù)圖像網(wǎng)站Desmos

    好玩又實(shí)用的查看函數(shù)圖像網(wǎng)站Desmos

    這個(gè)網(wǎng)站的最大優(yōu)點(diǎn),就是省去了安裝數(shù)學(xué)繪圖軟件或計(jì)算軟件的麻煩,只要打開(kāi)瀏覽器就能使用了。看了介紹之后,可別忘了把這個(gè)好網(wǎng)站加到書(shū)簽
    2021-08-08
  • 淺談軟件工程師的自我修養(yǎng)

    淺談軟件工程師的自我修養(yǎng)

    在本文中,我們將探討軟件開(kāi)發(fā)過(guò)程中關(guān)于角色、重構(gòu)和質(zhì)量的問(wèn)題。軟件不僅成為了一個(gè)必需品,更成為了一個(gè)競(jìng)爭(zhēng)優(yōu)勢(shì)。因?yàn)楸姸喙緡@軟件而競(jìng)爭(zhēng),軟件開(kāi)發(fā)相關(guān)的事宜顯得越發(fā)重要。開(kāi)發(fā)軟件的人—軟件工程師正顯得越發(fā)重要。
    2021-05-05
  • ffmpeg播放器實(shí)現(xiàn)詳解之視頻顯示(推薦)

    ffmpeg播放器實(shí)現(xiàn)詳解之視頻顯示(推薦)

    FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序。這篇文章主要介紹了ffmpeg播放器實(shí)現(xiàn)詳解視頻顯示,需要的朋友可以參考下
    2020-07-07

最新評(píng)論