アットウィキロゴ

Example8.6

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

Example8.6 - (2011/02/24 (木) 08:44:50) のソース

#co(){
8.6 Functions

Scala is a functional language in that functions are first-class values. Scala is also an object-oriented language in that every value is an object. It follows that functions are objects in Scala. For instance, a function from type String to type Int is represented as an instance of the trait Function1[String, Int]. The Function1 trait is defined as follows. 
}


#setmenu2(ex-r-menu)
** 8.6 関数 (Functions)

関数が第一級クラス値であるという点で Scala は関数型言語です。Scala はすべての値がオブジェクトであるという点でオブジェクト指向言語です。したがって Scala では関数はオブジェクトです。たとえば、型 String から型 Int への関数は、トレイト Function1[String, Int] のインスタンスとして表現されます。Function1 トレイトは次のように定義されます。

 package scala 
   trait Function1[-A, +B] { 
   def apply(x: A): B 
 } 

#co(){
Besides Function1, there are also definitions of for functions of all other arities (the current implementation implements this only up to a reasonable limit). That is, there is one definition for each possible number of function parameters. Scala's function type syntax (T1 , . . . , Tn) => S is simply an abbreviation for the parameterized type Functionn[T1 , . . . , Tn , S ] .} 

Function1 の他にも、異なるすべてのアリティ(項数)の関数に対して,定義があります (現在は、適正値までしか実装されていません) 。つまり、関数のパラメータの数ごとに定義があるということです。Scala の関数型構文 (T1,...,Tn) => S は、単に、パラメータ化された型 Functionn[T1,...,Tn,S] の省略形です。

#co(){
Scala uses the same syntax f (x ) for function application, no matter whether f is a method or a function object. This is made possible by the following convention: A function application f (x ) where f is an object (as opposed to a method) is taken to be a shorthand for f .apply(x ). Hence, the apply method of a function type is inserted automatically where this is necessary. }

Scala は f がメソッドか関数かに関わらず、同じ構文 f(x) を関数適用に用います。これは、「 f が (メソッドではなく)オブジェクトである時、関数適用 f(x) は f.apply(x) の省略形であるとみなす」という規則に従うことで可能となります。したがって関数型の apply メソッドは必要なときに自動的に挿入されます。

#co(){
That's also why we defined array subscripting in Section 8.2 by an apply method. For any array a, the subscript operation a(i) is taken to be a shorthand for a.apply(i). 
}

これは 8.2 節で、配列の添字化を apply メソッドで定義したのと同じです。あらゆる配列 a について、添字操作 a(i) は a.apply(i) の省略とみなされます。

#co(){
Functions are an example where a contra-variant type parameter declaration is useful. For example, consider the following code: 
}

関数は反変の型パラメータ宣言の有用な例です。たとえば次のコードを考えてみましょう。

 val f: (AnyRef => Int) = x => x.hashCode() 
 val g: (String => Int) = f 
 g("abc") 

#co(){
It's sound to bind the value g of type String => Int to f, which is of type AnyRef => Int. Indeed, all one can do with function of type String => Int is pass it a string in order to obtain an integer. Clearly, the same works for function f: If we pass it a string (or any other object), we obtain an integer. This demonstrates that function subtyping is contra-variant in its argument type whereas it is covariant in its result type. In short, S => T is a subtype of S' => T' , provided S' is a subtype of S and T is a subtype of T' . 
}

型 String => Int の値 g を、型 AnyRef => Int の f に束縛するのは健全です。実際、型 String => Int の関数を使ってできることは、整数を得るために文字列を渡すことなのですから。明らかに関数 f は同じように動作します。文字列 (あるいは任意のオブジェクト) を渡せば整数を得ます。これによって関数のサブタイプ化は、引数については反変ですが、結果型に対しては共変です。簡単に言うと、S' が S のサブタイプで、T が T' のサブタイプなら、S=>T は S'=>T' のサブタイプです。

#co(){
Example 8.6.1 Consider the Scala code 
}

&b(){Example 8.6.1 } 次の Scala コードについて考察しなさい。

 val plus1: (Int => Int) = (x: Int) => x + 1 
 plus1(2) 

#co(){
This is expanded into the following object code. 
}

これは次のオブジェクトコードに展開されます。

 val plus1: Function1[Int, Int] = new Function1[Int, Int] { 
   def apply(x: Int): Int = x + 1 
 } 
 plus1.apply(2) 

#co(){{
Here, the object creation new Function1[Int, Int]{ ... } represents an instance of an anonymous class. It combines the creation of a new Function1 object with an implementation of the apply method (which is abstract in Function1). Equivalently, but more verbosely, one could have used a local class: 
}}

ここでオブジェクト生成 new Function1[Int,Int]{...} は、&bold(){無名クラス}のインスタンスを表しています。これは新しい Function1 オブジェクトの生成と apply メソッド (Function1 では抽象メソッド) の実装を結びつけます。同じことを冗長にはなりますが、局所クラスを使っても書けます。

 val plus1: Function1[Int, Int] = { 
   class Local extends Function1[Int, Int] { 
     def apply(x: Int): Int = x + 1 
   } 
   new Local: Function1[Int, Int] 
 } 
 plus1.apply(2)

#center(){[[前ページ>Example8.5]] [[ 8 章>Chapter 8 Generic Types and Methods]] [[目次>ScalaByExample和訳]] [[次ページ>Chapter 9 Lists]]}

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

下から選んでください:

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