Example4.5

「Example4.5」の編集履歴(バックアップ)一覧はこちら

Example4.5」(2011/02/24 (木) 08:32:07) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

#co(){ 4.5 Nested Functions The functional programming style encourages the construction of many small helper functions. In the last example, the implementation of sqrt made use of the helper functions sqrtIter, improve and isGoodEnough. The names of these functions are relevant only for the implementation of sqrt. We normally do not want users of sqrt to access these functions directly. We can enforce this (and avoid name-space pollution) by including the helper functions within the calling function itself: } ** 4.5 ネストした関数 関数型プログラミングスタイルでは、小さなヘルパー関数をたくさん作ることを推奨しています。先の例では、sqrt の実装はヘルパー関数 sqrtIter、improve、isGoodEnough を使っています。これらの関数の名前は sqrt の実装にだけ関係します。ふつう我々は、sqrt のユーザーがこれらの関数に直接アクセスすることを望みません。 そうすることを (そして名前空間の汚染を避けるのを)、ヘルパー関数を呼び出す関数自身の中へ入れることで強制できます。 def sqrt(x: Double) = { def sqrtIter(guess: Double, x: Double): Double = if (isGoodEnough(guess, x)) guess else sqrtIter(improve(guess, x), x) def improve(guess: Double, x: Double) = (guess + x / guess) / 2 def isGoodEnough(guess: Double, x: Double) = abs(square(guess) - x) < 0.001 sqrtIter(1.0, x) } #co(){{ In this program, the braces { ... } enclose a block. Blocks in Scala are themselves expressions. Every block ends in a result expression which defines its value. The result expression may be preceded by auxiliary definitions, which are visible only in the block itself. }} このプログラムにおいて、中括弧 {...} は&bold(){ブロック}を囲みます。Scala のブロックはそれ自身が式です。各ブロックはその値を定義する結果式で終わります。結果式の前には補助的な定義があってもよく、それらはそのブロック内からしか見えません。 #co(){ Every definition in a block must be followed by a semicolon, which separates this definition from subsequent definitions or the result expression. However, a semicolon is inserted implicitly at the end of each line, unless one of the following conditions is true. - 1. Either the line in question ends in a word such as a period or an infix-operator which would not be legal as the end of an expression. - 2. Or the next line begins with a word that cannot start a expression. - 3. Or we are inside parentheses (...) or brackets , because these cannot contain multiple statements anyway. Therefore, the following are all legal: } ブロック内の各定義は、後にセミコロンが続かねばならず、それによって後に続く定義や結果式と分離されます。しかし、次の条件の何れかが真でなければ、各行の最後にセミコロンが暗黙のうちに挿入されます。 - 1. 問題となる行がピリオドのような単語や、式の最後として正しくない中置演算子で終わる場合。 - 2. あるいは次の行が、式のはじまりとならないような単語で始まる場合。 - 3. あるいは括弧 (...) または、角括弧 [...] の内側にいる場合 (これらの中に複数の文を入れることはできません)。 したがって次は正しいです。 def f(x: Int) = x + 1; f(1) + f(2) def g1(x: Int) = x + 1 g(1) + g(2) def g2(x: Int) = {x + 1}; /* ';' は必須 */ g2(1) + g2(2) def h1(x) = x + y h1(1) * h1(2) def h2(x: Int) = ( x // 括弧は必須。 + y // 括弧がないと 'x' の後にセミコロンが挿入される。 ) h2(1) / h2(2) #co(){ Scala uses the usual block-structured scoping rules. A name defined in some outer block is visible also in some inner block, provided it is not redefined there. This rule permits us to simplify our sqrt example. We need not pass x around as an additional parameter of the nested functions, since it is always visible in them as a parameter of the outer function sqrt. Here is the simplified code: } Scala は通常のブロック構造のスコープ規則を用いています。外側のブロックで定義された名前は、そこで再定義されない限り、内側のブロックからも見えます。この規則によって sqrt の例を簡略化できます。ネストさせた関数の追加引数として x を渡す必要はありません。なぜなら外側の関数 sqrt の引数は常に見えるからです。次が簡略化されたコードです。 def sqrt(x: Double) = { def sqrtIter(guess: Double): Double = if (isGoodEnough(guess)) guess else sqrtIter(improve(guess)) def improve(guess: Double) = (guess + x / guess) / 2 def isGoodEnough(guess: Double) = abs(square(guess) - x) < 0.001 sqrtIter(1.0) } #center(){[[前ページ>Example4.4]] [[ 4 章>ExampleChap4]] [[目次>ScalaByExample和訳]] [[次ページ>Example4.6]]} ---- - 「ギュ」は「行」のtypoでしょうか。あと、翻訳お疲れ様です。日本語でアクセスできるまとまったScalaの資料はまだ無いので、宮本さんの作業はたいへんすばらしいものだと思います。 -- みずしま (2008-04-15 21:34:58) - ご指摘ありがとうございます>みずしまさん。typo直しました。専門用語など心もとないと自覚があるので、随時ご指摘願えればと思います。 -- tmiya (2008-04-16 21:50:33) #comment
#co(){ 4.5 Nested Functions The functional programming style encourages the construction of many small helper functions. In the last example, the implementation of sqrt made use of the helper functions sqrtIter, improve and isGoodEnough. The names of these functions are relevant only for the implementation of sqrt. We normally do not want users of sqrt to access these functions directly. We can enforce this (and avoid name-space pollution) by including the helper functions within the calling function itself: } #setmenu2(ex-r-menu) ** 4.5 ネストした関数 関数型プログラミングスタイルでは、小さなヘルパー関数をたくさん作ることを推奨しています。先の例では、sqrt の実装はヘルパー関数 sqrtIter、improve、isGoodEnough を使っています。これらの関数の名前は sqrt の実装にだけ関係します。ふつう我々は、sqrt のユーザーがこれらの関数に直接アクセスすることを望みません。 そうすることを (そして名前空間の汚染を避けるのを)、ヘルパー関数を呼び出す関数自身の中へ入れることで強制できます。 def sqrt(x: Double) = { def sqrtIter(guess: Double, x: Double): Double = if (isGoodEnough(guess, x)) guess else sqrtIter(improve(guess, x), x) def improve(guess: Double, x: Double) = (guess + x / guess) / 2 def isGoodEnough(guess: Double, x: Double) = abs(square(guess) - x) < 0.001 sqrtIter(1.0, x) } #co(){{ In this program, the braces { ... } enclose a block. Blocks in Scala are themselves expressions. Every block ends in a result expression which defines its value. The result expression may be preceded by auxiliary definitions, which are visible only in the block itself. }} このプログラムにおいて、中括弧 {...} は&bold(){ブロック}を囲みます。Scala のブロックはそれ自身が式です。各ブロックはその値を定義する結果式で終わります。結果式の前には補助的な定義があってもよく、それらはそのブロック内からしか見えません。 #co(){ Every definition in a block must be followed by a semicolon, which separates this definition from subsequent definitions or the result expression. However, a semicolon is inserted implicitly at the end of each line, unless one of the following conditions is true. - 1. Either the line in question ends in a word such as a period or an infix-operator which would not be legal as the end of an expression. - 2. Or the next line begins with a word that cannot start a expression. - 3. Or we are inside parentheses (...) or brackets , because these cannot contain multiple statements anyway. Therefore, the following are all legal: } ブロック内の各定義は、後にセミコロンが続かねばならず、それによって後に続く定義や結果式と分離されます。しかし、次の条件の何れかが真でなければ、各行の最後にセミコロンが暗黙のうちに挿入されます。 - 1. 問題となる行がピリオドのような単語や、式の最後として正しくない中置演算子で終わる場合。 - 2. あるいは次の行が、式のはじまりとならないような単語で始まる場合。 - 3. あるいは括弧 (...) または、角括弧 [...] の内側にいる場合 (これらの中に複数の文を入れることはできません)。 したがって次は正しいです。 def f(x: Int) = x + 1; f(1) + f(2) def g1(x: Int) = x + 1 g(1) + g(2) def g2(x: Int) = {x + 1}; /* ';' は必須 */ g2(1) + g2(2) def h1(x) = x + y h1(1) * h1(2) def h2(x: Int) = ( x // 括弧は必須。 + y // 括弧がないと 'x' の後にセミコロンが挿入される。 ) h2(1) / h2(2) #co(){ Scala uses the usual block-structured scoping rules. A name defined in some outer block is visible also in some inner block, provided it is not redefined there. This rule permits us to simplify our sqrt example. We need not pass x around as an additional parameter of the nested functions, since it is always visible in them as a parameter of the outer function sqrt. Here is the simplified code: } Scala は通常のブロック構造のスコープ規則を用いています。外側のブロックで定義された名前は、そこで再定義されない限り、内側のブロックからも見えます。この規則によって sqrt の例を簡略化できます。ネストさせた関数の追加パラメータとして x を渡す必要はありません。なぜなら外側の関数 sqrt のパラメータは常に見えるからです。次が簡略化されたコードです。 def sqrt(x: Double) = { def sqrtIter(guess: Double): Double = if (isGoodEnough(guess)) guess else sqrtIter(improve(guess)) def improve(guess: Double) = (guess + x / guess) / 2 def isGoodEnough(guess: Double) = abs(square(guess) - x) < 0.001 sqrtIter(1.0) } #center(){[[前ページ>Example4.4]] [[ 4 章>ExampleChap4]] [[目次>ScalaByExample和訳]] [[次ページ>Example4.6]]} ---- - 「ギュ」は「行」のtypoでしょうか。あと、翻訳お疲れ様です。日本語でアクセスできるまとまったScalaの資料はまだ無いので、宮本さんの作業はたいへんすばらしいものだと思います。 -- みずしま (2008-04-15 21:34:58) - ご指摘ありがとうございます>みずしまさん。typo直しました。専門用語など心もとないと自覚があるので、随時ご指摘願えればと思います。 -- tmiya (2008-04-16 21:50:33) #comment

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。