第6章高階関数
引数として6.1
別の変数の関数として関数に渡され、パラメータの関数としてタイプがある:すなわち、機能1:
(パラメータタイプ)=>戻り値
// 6.1パラメータとして DEF PLUS(X:INT)= 3 + X ヴァル結果1は、アレイ=(1,2 ,. 3 ,. 4。).MAP(PLUS(_)) のprintln(result1.mkString( ""))
ヒントをスクリーミング:2つのパラメータはように機能2であり、との関数パラメータのタイプでは、はfunction1です。
注意:
// パラメータとして6.1 DEF MATCH1()ダウン:単位= { DEF PLUS(X:INT) = 3 + X ヴァル結果1は、アレイ=(1,2 ,. 3 ,. 4。.MAP(PLUS(_))) のprintln(結果1 (.mkString ""))// 4,5,6,7 } MATCH1ダウン()
6.2匿名関数
名前のないこの関数は、無名関数は関数式で設定することができます。
トリプル=ヴァル(X:ダブル)=> 3 *。X
のprintln(トリプル(3)。) // 使用方法: アレイ(3.14、1.42、2.0 ).MAP(トリプル) // に()に含まれる 配列(3.14、1.42 2.0).MAP。((X:ダブル)=> 3 * X)は // {}に含まれる 配列(3.14、1.42、2.0)マップ{(X:ダブル)=> 3 * X}
注意:
// 6.2匿名関数 DEFのMATCH2、():単位= { ヴァルトリプル =(X:ダブル)=> 3 * X のprintln(トリプル( 3 ))//9.0 // 使用: のprintln(配列(3.14、1.42、2.0 ).MAP(トリプル).mkString( "" ))//9.42、4.26、6.0 // (に含まれる)で のprintln(配列(3.14、1.42、 2.0).MAP((X:ダブル)=> 3 * X).mkString( "" )) // {}内に囲ま のprintln(配列(3.14、1.42、2.0){マップ(X:ダブル)=> X}。3 mkString *( "" )) } MATCH2、( )
6.3高階関数
あなたは高階関数と呼ばれる引数としての機能を受け入れることができます。
高次機能の1)使用
DEF highOrderFunction1(F:ダブル=>ダブル)= F(10 ) デフminus7(X:ダブル) = X -7 ヴァル結果2 = highOrderFunction1(minus7) のprintln(結果2)
2)同じ高次関数は、関数のタイプを返すことができます
DEF minusxy(X:INT)=(Y:INT)=> X - Y ヴァルresult3 = minusxy(3)〜(5 ) のprintln(result3)
6.4パラメータ(タイプ)推論
// 関数式に渡される (:ダブル)=> 3 *(X valueAtOneQuarter X) // パラメータ推定省略形情報 valueAtOneQuarter((X)=> 3 * X) // 単一のパラメータを省略してもよい括弧 valueAtOneQuarter(X => 3 * X-) // 変数が意図されている場合は=>は一度だけ、右に表示され、あなたが交換するために使用することができます_ valueAtOneQuarter(3 * _を)
6.5クロージャ
閉鎖も含まれていることを所有していない外部オブジェクトの関数である(閉じた状態)に来ました。
DEF minusxy(X:INT)=(Y:INT)=> X - Y のprintln( minusxy ( 10)(20))
これは閉鎖され
1)匿名関数(Y:INT)=>のx - yは、ネストされた関数をminusxy。
外部変数、ローカル変数xのmulByを用いてY - INT)=> X:2)匿名関数(X。ないグローバル変数
3)minusxy機能は、匿名関数は、ローカル変数を参照返します。
別の例:
DEF minusxy(X:INT)=(Y:INT)=> X - Y ヴァルF1 = minusxy(10 ) ヴァルF2 = minusxy(10 ) のprintln(F1( 3)+ F2(3))
ここでF1、F2これら二つの機能が閉鎖と呼ばれています。
6.6カリー化
プログラミング機能、複数のパラメータを受信する機能は、機能つのパラメータを受け付けるに変換することができ、
この変換プロセスは、カリー化関数が1つのみのパラメータを証明するためだった、カリー化と呼ばれています。
1)実施例カリー化
// 二つのパラメータの伝統的な定義 = X * DEF MUL(:INT、YのInt X)Y のprintln(MUL( 6、7である)) // クロージャに使用カレー定義、 = mulOneAtATime(中間体X)DEF (Y:INT)=> X * Y のprintln(mulOneAtATime( 6)(7。 )) // Scalaは略すことが DEF mulOneAtATime(X:INT)(Y:INT)= X * Y のprintln(mulOneAtATime( 10)(8 ))
カリー化の2)応用
2つの文字列が、ノートの下で再びケースを無視して等しい比較、ここでは2つのタスクがあります:
図1に示すように、すべて大文字(小文字)を転送
2、より平等
これら二つの操作のために、我々は実際には、不注意に2つの関数の思考プロセスとなっている、機能に対処する考え。
例としては、次のとおりです:
ヴァル=配列( "こんにちは"、 "世界" ) ヴァル・B =配列( "こんにちは"、 "世界" ) // DEF対応[B](つまり:GenSeq [B])(P:(A、B)= >ブール):ブール のprintln(a.corresponds(b)は(_ equalsIgnoreCase(_)。))
定義された関数を使用してカリー化対応します
ソースは以下のとおりです。
DEF相当[B](つまり:GenSeq [B])(P(A、B)=>ブール):ブール= { ヴァルI = この.iterator ヴァルJ = that.iterator 一方(i.hasNext && j.hasNext ) 場合(!P(i.next()、j.next())) を返す 偽 !i.hasNext &&を!j.hasNext }
6.7抽象化
抽象化は、関数のクラスです。
図1は、パラメータの関数です。
図2に示すように、無入力関数パラメータ値を返しません。
1)使用の例:
runInThread DEF(ブロック:()=> 単位){ 新しい新しいスレッド{ オーバーライドDEF RUN(){ブロック()} } .start() }
// 関数に渡さ runInThread {()=> printlnを( "こんにちは");スレッド.sleep(10000);のprintln(「さようなら」)} () =>やや冗長には、呼び出しを示すために、名前を変更するために使用することができ、省略()保持=> // この関数が呼び出される抽象コントロールは、(キーのプログラミング言語のように見えます機能語) DEF runInThread(ブロック:=> ユニット){ 新しい新しいスレッド{ オーバーライドDEF RUN(){ブロック} } .start() }
// エレガント着信 runInThread {のprintln( "こんにちは") ;のThread.sleep( 1000);のprintln( "さようなら")}
//同様の定義ながらまで機能 (条件までDEF:=>ブール)(ブロック:=> ユニット){ もし!(条件){ ブロック まで(条件)(ブロック) } }
VAR X = 10
になるまで(x == 0){
X - = 1つ
のprintln(X)
}
注意:
// 6.7抽象 DEF runOnThread(F1 :()=>ユニット)単位= { 新しい新しいスレッド{ オーバーライドDEF RUN():単位 = { F1() } } .start() } runOnThread({ () =>のprintln ( "!働く" ) のThread.sleep( 5000 ) のprintln(「仕事を終える'! ) }) // ()=> 1; 2; 3 + 1