Scala布教の会(4)関数発展

Jyonsty
記事: 3
登録日時: 13年前

Scala布教の会(4)関数発展

投稿記事 by Jyonsty » 13年前

さて。三日坊主じゃないぞScala布教の会。
前回は関数型言語特有の値としての関数の使い方を学びました。
今回は特殊な関数の呼び出し方から。
まずはクロージャー。(と前回書くつもりで書き忘れたとこ。)

CODE:

val addmore0 = (x : Int) => x + more //この書き方ではmoreに値が入ってないからエラーが起こる。
//------------------------------------------
var more = 5
val addmore1 = (x : Int) =>x + more //一応エラーは起きない。でもさぁ、引数以外の外部の値に関数の結果が依存してるってのはなぁ。
//------------------------------------------
def addmore2(more:Int) = (x : Int) => x + more  //外部の値moreを使わずに書けた。キャー素敵。
まずはじめの関数は「more」という値が定義されてないのでエラーが起きます。
次の関数はその問題点を補ってmore = 5としたのでエラーは起きません。
このときのmoreを自由変数といい、逆にxを束縛変数といいます。
そして、関数リテラルが実行されるときに生成される関数のことを「クロージャー」といいます。
今、moreは自由変数なので、addmore1の呼び出しの時に、

CODE:

more = 111
val i = addmore1(888)
とやると、ちゃんとmoreの値が反映されてi = 999となります。
すなわち、クロージャーは生成時にmoreへの参照をつかんでいます。
でもさぁ、moreって値がバンバン変わるからそれに依存した関数書くってのもなぁ。

ようやく本題のaddmore2関数。
この関数はいわば、「クロージャーを返す関数」です。
例えばこんな感じでつかいます。

CODE:

val add111 = addmore2(111)  //addmore2関数内のmoreの値を111に固定したクロージャーを返す。
val add333 = addmore2(333)  //addmore2関数内のmoreの値を333に固定したクロージャーを返す。
val i = add111(21)   //x(21) + 111 = 132
val j = add333(21)  //x(21)  + 333 = 354
ここの関数で生成されるクロージャは、moreへの参照ではなく、
生成時に固定された111や333といった値をつかんでいます。

次は名前つき引数とデフォルト値の指定。

CODE:

def printarea(width:Int = 10,height:Int = 10) = println(width*height)
printarea(15,12)   //こうも使えるけど…
printarea(height = 12,width = 15)//こうも使えるし、
printarea() //こうも使えるよ(100が出力されます。)っていう。
今回はこの辺にします。
次回は関数のカリー化と名前渡し関数です。(いつ終われるんだ?関数。)

naohiro19
記事: 256
登録日時: 15年前

RE: Scala布教の会(4)関数発展

投稿記事 by naohiro19 » 12年前

「クロージャ」という意味を別名では「ラムダ」と言われてますね。