scala-コヒーレント、インバータ、上界、下界
7664 ワード
ソースコードのテスト
注目を集めてください:scalaツールライブラリ、各種ライブラリのテスト例と使用説明ドキュメントの説明ドキュメントが含まれています
コヒーレントタイプList[A+]を定義すると、List[Child]はList[Parent]のサブタイプとすることができる.
逆変換タイプList[−A]を定義すると、List[Child]は、List[parent]の親タイプであってもよい.
Scalaのコヒーレンス
次の例を見てください.
cは、Covariantが不変タイプとして定義されているため、c 2に値を割り当てることはできません.
少し変更します.
Consumerはコヒーレントタイプとして定義されるため、Covariant[Bird]はCovariant[Animal]のサブタイプであるため、c 2に付与することができる.
Scalaのインバータ
上記の例を変更します.
ここでConsumer[-T]はインバータタイプとして定義されるので、Contravariant[Animal]はContravariant[Animal]のサブタイプと見なされ、cはc 2に付与される.
下界lower bounds
コヒーレントクラスにタイプパラメータ付きメソッドが含まれている場合:
コンパイル中にエラーが発生します.エラーメッセージは、「Covariant type T occurs in contravariant position in type T of value t」です.ただし、結果がタイプパラメータの場合は問題ありません.
メソッドのパラメータでタイプパラメータを使用するには、次の境界を定義する必要があります.
この場所は比較的複雑で、簡単に言えばScala内部実装は、クラスの中のすべての置くことができるタイプの場所を分類(+,—,中立)し、具体的な分類規則はここの最外層クラス[+T]に対してコヒーレントであるとは言わないが、方法のタイプパラメータになると、この位置が反転して-逆の位置になるので、Tを彼にあげ、コヒーレントタイプをインバータの位置に置いたと勘違いします
だからここの処理の方法は、彼がインバータを要して、彼にインバータをあげて、[U>:T]を使って、その中のTは下界で、TあるいはTのスーパークラスを表して、このようにScalaコンパイラは間違いを報告しません
上界upper bounds
インバータクラスで上界を使用する例を見てみましょう.
メソッドの戻り値はコヒーレントな位置であり,メソッドのパラメータは逆の位置であることがわかる.したがって、コヒーレントクラスのタイプパラメータは、メソッドの戻り値のタイプで使用できます.メソッドのパラメータタイプでは、下限バインド>を使用する必要があります.インバータクラスのタイプパラメータはメソッドのパラメータタイプに使用でき、メソッドの戻り値タイプとして使用する場合は上界バインド<:.
総合コヒーレンス
1つの総合例:
View Bound <%
Scalaには、ビューバインドの機能もあります.
または、タイプパラメータはメソッド上:
これは、TがBird、すなわちT=>Birdに変換できる暗黙的な変換が必要であることを要求する.そうしないと、上のコードはコンパイルエラーを起こす:No implicit view available from Toy=>Bird.暗黙的な変換を追加し、コンパイルします.
Context Bound
context boundはScala 2.8.0に導入され、type class patternとも呼ばれる.view boundはA<%String方式を用い,context boundはOrdered[A]のようなパラメトリックなタイプを必要とする.それは1つのタイプAを宣言して、暗黙的に1つのタイプB[A]があって、文法は以下の通りです:
より明確な例:
例えば
リファレンス
Scalaにおけるコヒーレンス,インバータ,上界,下界など
Scalaのコヒーレンスとインバータの上界と下界
コヒーレントポイントとインバータポイント
注目を集めてください:scalaツールライブラリ、各種ライブラリのテスト例と使用説明ドキュメントの説明ドキュメントが含まれています
コヒーレントタイプList[A+]を定義すると、List[Child]はList[Parent]のサブタイプとすることができる.
逆変換タイプList[−A]を定義すると、List[Child]は、List[parent]の親タイプであってもよい.
Scalaのコヒーレンス
次の例を見てください.
class Animal {}
class Bird extends Animal {}
class Animal {}
class Bird extends Animal {}
//
class Covariant[T](t:T){}
val cov = new Covariant[Bird](new Bird)
val cov2:Covariant[Animal] = cov
cは、Covariantが不変タイプとして定義されているため、c 2に値を割り当てることはできません.
少し変更します.
class Animal {}
class Bird extends Animal {}
class Animal {}
class Bird extends Animal {}
//
class Covariant[+T](t:T){}
val cov = new Covariant[Bird](new Bird)
val cov2:Covariant[Animal] = cov
Consumerはコヒーレントタイプとして定義されるため、Covariant[Bird]はCovariant[Animal]のサブタイプであるため、c 2に付与することができる.
Scalaのインバータ
上記の例を変更します.
class Animal {}
class Bird extends Animal {}
class Contravariant[-T](t: T) {
}
val c: Contravariant[Animal] = new Contravariant[Animal](new Animal)
val c2: Contravariant[Bird] = c
ここでConsumer[-T]はインバータタイプとして定義されるので、Contravariant[Animal]はContravariant[Animal]のサブタイプと見なされ、cはc 2に付与される.
下界lower bounds
コヒーレントクラスにタイプパラメータ付きメソッドが含まれている場合:
class Animal {}
class Bird extends Animal {}
class Consumer[+T](t: T) {
def use(t: T) = {}
}
コンパイル中にエラーが発生します.エラーメッセージは、「Covariant type T occurs in contravariant position in type T of value t」です.ただし、結果がタイプパラメータの場合は問題ありません.
class Animal {}
class Bird extends Animal {}
class Consumer[+T](t: T) {
def get(): T = {new T}
}
メソッドのパラメータでタイプパラメータを使用するには、次の境界を定義する必要があります.
class Animal {}
class Bird extends Animal {}
class Consumer[+T](t: T) {
def use[U >: T](u : U) = {println(u)}
}
この場所は比較的複雑で、簡単に言えばScala内部実装は、クラスの中のすべての置くことができるタイプの場所を分類(+,—,中立)し、具体的な分類規則はここの最外層クラス[+T]に対してコヒーレントであるとは言わないが、方法のタイプパラメータになると、この位置が反転して-逆の位置になるので、Tを彼にあげ、コヒーレントタイプをインバータの位置に置いたと勘違いします
だからここの処理の方法は、彼がインバータを要して、彼にインバータをあげて、[U>:T]を使って、その中のTは下界で、TあるいはTのスーパークラスを表して、このようにScalaコンパイラは間違いを報告しません
上界upper bounds
インバータクラスで上界を使用する例を見てみましょう.
class Animal {}
class Bird extends Animal {}
class Consumer[-T](t: T) {
def get[U <: T](): U = {new U}
}
メソッドの戻り値はコヒーレントな位置であり,メソッドのパラメータは逆の位置であることがわかる.したがって、コヒーレントクラスのタイプパラメータは、メソッドの戻り値のタイプで使用できます.メソッドのパラメータタイプでは、下限バインド>を使用する必要があります.インバータクラスのタイプパラメータはメソッドのパラメータタイプに使用でき、メソッドの戻り値タイプとして使用する場合は上界バインド<:.
総合コヒーレンス
1つの総合例:
class Animal {}
class Bird extends Animal {}
class Consumer[-S,+T]() {
def m1[U >: T](u: U): T = {new T} // ,
def m2[U <: S](s: S): U = {new U} // ,
}
class Test extends App {
val c:Consumer[Animal,Bird] = new Consumer[Animal,Bird]()
val c2:Consumer[Bird,Animal] = c
c2.m1(new Animal)
c2.m2(new Bird)
}
View Bound <%
Scalaには、ビューバインドの機能もあります.
class Bird {def sing = {}}
class Toy {}
class Consumer[T <% Bird]() {
def use(t: T) = t.sing
}
または、タイプパラメータはメソッド上:
class Bird {def sing = {}}
class Toy {}
class Consumer() {
def use[T <% Bird](t: T) = t.sing
}
class Test extends App {
val c = new Consumer()
c.use(new Toy)
}
これは、TがBird、すなわちT=>Birdに変換できる暗黙的な変換が必要であることを要求する.そうしないと、上のコードはコンパイルエラーを起こす:No implicit view available from Toy=>Bird.暗黙的な変換を追加し、コンパイルします.
import scala.language.implicitConversions
class Bird {def sing = {}}
class Toy {}
class Consumer() {
def use[T <% Bird](t: T) = t.sing
}
class Test extends App {
implicit def toy2Bird(t: Toy) = new Bird
val c = new Consumer()
c.use(new Toy)
}
Context Bound
context boundはScala 2.8.0に導入され、type class patternとも呼ばれる.view boundはA<%String方式を用い,context boundはOrdered[A]のようなパラメトリックなタイプを必要とする.それは1つのタイプAを宣言して、暗黙的に1つのタイプB[A]があって、文法は以下の通りです:
def f[A : B](a: A) = g(a) // where g requires an implicit value of type B[A]
より明確な例:
def f[A : ClassManifest](n: Int) = new Array[A](n)
例えば
def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)
リファレンス
Scalaにおけるコヒーレンス,インバータ,上界,下界など
Scalaのコヒーレンスとインバータの上界と下界
コヒーレントポイントとインバータポイント