Example8.3

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

Example8.3 - (2011/02/24 (木) 08:42:31) の1つ前との変更点

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

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

#co(){ 8.3 Lower Bounds We have seen upper bounds for type parameters. In a type parameter declaration such as T <: U, the type parameter T is restricted to range only over subtypes of type U. Symmetrical to this are lower bounds in Scala. In a type parameter declaration T >: S, the type parameter T is restricted to range only over supertypes of type S. (One can also combine lower and upper bounds, as in T >: S <: U.) Using lower bounds, we can generalize the push method in Stack as follows. } ** 8.3 下限境界 (Lower Bounds) 型パラメータの上限境界について見てきました。T <: U のような型パラメータ宣言では、型パラメータ T は型 U のサブタイプの範囲に制限されます。これと対照的なのが Scala における下限境界です。型パラメータ宣言 T >: S において、型パラメータ T は型 S の&bold(){スーパータイプ}の範囲に制限されます (上限境界と下限境界を組み合わせることもできます。T >: S <: U のように)。 下限境界を用いると、Stack の push メソッドを次のように一般化できます。 class Stack[+A] { def push[B >: A](x: B): Stack[B] = new NonEmptyStack(x, this) #co(){ Technically, this solves our variance problem since now the type parameter A appears no longer as a parameter type of method push. Instead, it appears as lower bound for another type parameter of a method, which is classified as a co-variant position. Hence, the Scala compiler accepts the new definition of push. } 技術的には、これによって変位指定問題は解決します。なぜなら、型パラメータ A はいまや push メソッドの型パラメータではないからです。その代わり、メソッドの別の型パラメータの下限境界として現れ、その型パラメータは共変的な位置に分類されます。したがって Scala コンパイラは新しい push 定義を受け入れます。 #co(){ In fact, we have not only solved the technical variance problem but also have generalized the definition of push. Before, we were required to push only elements with types that conform to the declared element type of the stack. Now, we can push also elements of a supertype of this type, but the type of the returned stack will change accordingly. For instance, we can now push an AnyRef onto a stack of Strings, but the resulting stack will be a stack of AnyRefs instead of a stack of Strings! } 実際、変位指定の技術的な問題を解決しただけではなく、push 定義を一般化しました。以前は、スタックの宣言された要素型に適合する型のみプッシュできました。今では、この型のサブタイプの要素もプッシュできますが、戻り値のスタックの型は適宜変化します。たとえば String のスタックに AnyRef をプッシュできますが、戻るスタックは String のスタックではなく AnyRef のスタックなのです! #co(){ In summary, one should not hesitate to add variance annotations to your data structures, as this yields rich natural subtyping relationships. The compiler will detect potential soundness problems. Even if the compiler's approximation is too conservative, as in the case of method push of class Stack, this will often suggest a useful generalization of the contested method. } 要約すると、自分のデータ構造に変位指定アノテーションを付けることを躊躇すべきではありません。なぜならそれによって、リッチで自然なサブタイプ関係が得られるからです。コンパイラは健全性に関する潜在的な問題を見つけます。クラス Stack の push メソッドのようにコンパイラの推定が用心深すぎたとしても、問題となっているメソッドについて、有益な一般化をしばしば示唆します。 #center(){[[前ページ>Example8.2]] [[ 8 章>Chapter 8 Generic Types and Methods]] [[目次>ScalaByExample和訳]] [[次ページ>Example8.4]]} ---- #comment
d#co(){ 8.3 Lower Bounds We have seen upper bounds for type parameters. In a type parameter declaration such as T <: U, the type parameter T is restricted to range only over subtypes of type U. Symmetrical to this are lower bounds in Scala. In a type parameter declaration T >: S, the type parameter T is restricted to range only over supertypes of type S. (One can also combine lower and upper bounds, as in T >: S <: U.) Using lower bounds, we can generalize the push method in Stack as follows. } #setmenu2(ex-r-menu) ** 8.3 下限境界 (Lower Bounds) 型パラメータの上限境界について見てきました。T <: U のような型パラメータ宣言では、型パラメータ T は型 U のサブタイプの範囲に制限されます。これと対照的なのが Scala における下限境界です。型パラメータ宣言 T >: S において、型パラメータ T は型 S の&bold(){スーパータイプ}の範囲に制限されます (上限境界と下限境界を組み合わせることもできます。T >: S <: U のように)。 下限境界を用いると、Stack の push メソッドを次のように一般化できます。 class Stack[+A] { def push[B >: A](x: B): Stack[B] = new NonEmptyStack(x, this) #co(){ Technically, this solves our variance problem since now the type parameter A appears no longer as a parameter type of method push. Instead, it appears as lower bound for another type parameter of a method, which is classified as a co-variant position. Hence, the Scala compiler accepts the new definition of push. } 技術的には、これによって変位指定問題は解決します。なぜなら、型パラメータ A はいまや push メソッドの型パラメータではないからです。その代わり、メソッドの別の型パラメータの下限境界として現れ、その型パラメータは共変的な位置に分類されます。したがって Scala コンパイラは新しい push 定義を受け入れます。 #co(){ In fact, we have not only solved the technical variance problem but also have generalized the definition of push. Before, we were required to push only elements with types that conform to the declared element type of the stack. Now, we can push also elements of a supertype of this type, but the type of the returned stack will change accordingly. For instance, we can now push an AnyRef onto a stack of Strings, but the resulting stack will be a stack of AnyRefs instead of a stack of Strings! } 実際、変位指定の技術的な問題を解決しただけではなく、push 定義を一般化しました。以前は、スタックの宣言された要素型に適合する型のみプッシュできました。今では、この型のサブタイプの要素もプッシュできますが、戻り値のスタックの型は適宜変化します。たとえば String のスタックに AnyRef をプッシュできますが、戻るスタックは String のスタックではなく AnyRef のスタックなのです! #co(){ In summary, one should not hesitate to add variance annotations to your data structures, as this yields rich natural subtyping relationships. The compiler will detect potential soundness problems. Even if the compiler's approximation is too conservative, as in the case of method push of class Stack, this will often suggest a useful generalization of the contested method. } 要約すると、自分のデータ構造に変位指定アノテーションを付けることを躊躇すべきではありません。なぜならそれによって、リッチで自然なサブタイプ関係が得られるからです。コンパイラは健全性に関する潜在的な問題を見つけます。クラス Stack の push メソッドのようにコンパイラの推定が用心深すぎたとしても、問題となっているメソッドについて、有益な一般化をしばしば示唆します。 #center(){[[前ページ>Example8.2]] [[ 8 章>Chapter 8 Generic Types and Methods]] [[目次>ScalaByExample和訳]] [[次ページ>Example8.4]]} ---- #comment

表示オプション

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

下から選んでください:

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