Example4.5

「Example4.5」の編集履歴(バックアップ)一覧に戻る

Example4.5 - (2008/04/13 (日) 13:00:00) のソース

** 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: 

 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) 
 }

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. 

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: 

 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}; /* ‘;’ mandatory */ g2(1) + g2(2) 
 def h1(x) = 
   x + 
   y 
   h1(1) * h1(2)
  
 def h2(x: Int) = ( 
   x // parentheses mandatory, otherwise a semicolon 
   + y // would be inserted after the ‘x’. 
 )
 h2(1) / h2(2)

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: 

 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) 
 }

----
#comment
ツールボックス

下から選んでください:

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