在數學和電腦科學中,高階函式是至少滿足下列乙個條件的函式:
- 接受乙個或多個函式作為輸入
- 輸出乙個函式
在數學中它們也叫做運算元(運算子)或泛函。微積分中的導數就是常見的例子,因為它對映乙個函式到另乙個函式。
假設有乙個函式對給定兩個數區間中的所有整數求和:
def
sumints
(a: int, b: int): int =
if(a > b) 0
else a + sumints(a + 1, b)
如果現在要求連續整數的平方和:
def
square
(x: int): int = x * x
defsumsquares
(a: int, b: int): int =
if(a > b) 0
else square(a) + sumsquares(a + 1, b)
如果要計算2的冪次的和:
def
poweroftwo
(x: int): int = if(x == 0) 1
else
2 * poweroftwo(x-1)
defsumpowersoftwo
(a: int, b: int): int =
if(a > b) 0
else poweroftwo(a) + sumpowersoftwo(a+1, b)
上面的函式都是從a到b的f(n)的累加形式,我們可以抽取這些函式中共同的部分重新編寫函式sum,其中定義的f作為乙個引數傳入到高階函式sum中:
def
sum(f: int => int, a: int, b: int): int =
if(a > b) 0
else f(a) + sum(f, a+1, b)
defid
(x: int): int = x
defsquare
(x: int): int = x * x
defpoweroftwo
(x: int): int = if(x == 0) 1
else
2 * poweroftwo(x-1)
defsumints
(a: int, b: int): int = sum(id, a, b)
defsumsquared
(a: int, b: int): int = sum(square, a, b)
defsumpowersoftwo
(a: int, b: int): int = sum(poweroftwo, a, b)
map方法將乙個函式應用到某個集合的所有元素並返回結果;foreach將函式應用到每個元素。
//列印三角形
scala> (1 to 9).map("^" * _).foreach(println _)^^^
^^^^^^^
^^^^^
^^^^^^
^^^^^^^
^^^^^^^^
^^^^^^^^^
filter方法輸出所有匹配某個特定條件的元素:
scala> (1 to 9).filter(_ % 2 == 0)
res14: scala.collection.immutable.indexedseq[int] = vector(2, 4, 6, 8)
可以通過練習使用scala集合庫中的一些常用的接受函式引數的方法來熟悉高階函式。
柯里化(currying)指的是將原來接受兩個引數的函式變成新的接受乙個引數的函式的過程。新的函式返回乙個以原有第二個引數為引數的函式。
在上面高階函式的例子中,我們通過def sumints(a: int, b: int): int = sum(x => x, a, b)
、def sumsquared(a: int, b: int): int = sum(x => x*x, a, b)
來定義新的函式,上面這兩個函式每次都要傳入a和b兩個引數到sum函式中,我們能否簡化這些引數使得函式定義更簡單呢?
我們可以通過返回函式的函式來簡化引數:
def
sum(f: int => int): (int, int) => int =
//於是得到如下定義,這樣就簡化了引數
defsumints
= sum(x => x)
defsumsquared
= sum(x => x * x)
defsumpowersoftwo
= sum(poweroftwo)
根據上面的例子,我們能不能更加簡化,省去sumints
、sumsquared
、sumpowersoftwo
這幾個中間函式的形式呢?
通過sum(square)(1, 10)
函式來替代sumsquared
函式。
一般情況,這類函式的左結合的:sum(square)(1, 10) == (sum(square))(1, 10)
。
我們可以這樣定義sum函式:
def
sum(f: int => int)(a: int, b: int): int =
if(a > b) 0
else f(a) + sum(f)(a + 1, b)
這使得函式編寫更加簡潔。
一般的,多引數函式定義為def f(args1)...(argsn) = e
,
當n > 1時,等同於def f(args1)...(args n-1) =
或者def f(args1)...(args n-1) = (argsn => e)
。
如果重複這個過程n次,得到def f = (args1 => (args2 => ... (argsn => e) ) )
。
這種函式定義稱為柯里化(currying)。
Scala 函式柯里化
柯里化指的是將原來接受多個引數的函式變成新的接受乙個引數的函式的過程,新函式的引數接受原來的第二個引數為唯一引數,如果有n個引數,就是把這個函式分解成n個新函式的過程 1 函式程式設計中,接受多個引數的函式都可以轉化為接受單個引數的函式,這個轉化過程就叫柯里化 2 柯里化就是證明了函式只需要乙個引數...
scala 函式柯里化
1 函式程式設計中,接受多個引數的函式都可以轉化為接受單個引數的函式,這個轉化過程就叫柯里化 2 柯里化就是證明了函式只需要乙個引數而已。不重要 package com.xcu.chapter13 object demo05 curry 3 柯里化就是函最重要的是要體現函式的分工協作,例如乙個函式是...
Scala柯里化和反柯里化
名詞解釋 在電腦科學中,柯里化 currying 是把接受多個引數的函式變換成接受乙個單一引數 最初函式的第乙個引數 的函式,並且返回接受餘下的引數且返回結果的新函式的技術。柯里化舉例說明 def curry1 a,b,c a a,f a,b c b c b b f a,b 這個函式的結果是乙個高階...