私は今やscalaを使っていますが、私は実際にすべてを理解し始めていると思っていました。私は自分自身がMapクラスのいくつかのメソッド定義で混乱しているのを見つけました。私はfoldLeftなどの仕組みが分かっていますが、私が混乱しているのはMap関数で使用される型パラメータです。のは、一例としてfoldLeft使用してみましょう:特性/クラス型のパラメータが優先されるときのルールとメソッド型のパラメータ
foldLeft [B] (z: B)(op: (B, (A, B)) ⇒ B) : B
マップ形質自体の定義は、2つのタイプのパラメータ「A」および「B」(例えば地図[A + B])をとります。クラス/特性の型パラメータの1つと同じ名前を使用してメソッドの型パラメータを定義すると、クラス/特性値が上書きされます。例としてはFooのこの定義を取る:
class Foo[A : Manifest, B : Manifest] {
def isAString() = manifest[A] == manifest[String]
def isAInt() = manifest[A] == manifest[Int]
def isBString() = manifest[B] == manifest[String]
def isBInt() = manifest[B] == manifest[Int]
def nowIsBString[B : Manifest] = manifest[B] == manifest[String]
}
scala> val f = new Foo[String,Int]
f: Foo[String,Int] = [email protected]
scala> f.isAString
res290: Boolean = true
scala> f.isAInt
res291: Boolean = false
scala> f.isBString
res292: Boolean = false
scala> f.isBInt
res293: Boolean = true
scala> f.nowIsBString[String]
res294: Boolean = true
scala> f.nowIsBString[Int]
res295: Boolean = false
だからfoldLeft定義で、「B」はメソッドの定義から来て、「A」はトレイトの定義から来ています。たとえば、次のように
val xm = Map("test" -> 1, "test2" -> 2)
scala> val foldFn = (z: Int, kv: (String, Int)) => z + kv._2
foldFn: (Int, (String, Int)) => Int = <function2>
scala> m.foldLeft(0)(foldFn)
res298: Int = 3
私はintの代わりに文字列への機能のために「B」タイプを変更すると、これはと形質の機能マッチ「B」は「B」が、何として期待されています
scala> val foldFn = (z: String, kv: (String, String)) => z + kv._2
foldFn: (String, (String, String)) => java.lang.String = <function2>
scala> m.foldLeft("")(foldFn)
<console>:19: error: type mismatch;
found : (String, (String, String)) => java.lang.String
required: (java.lang.String, (java.lang.String, Int)) => java.lang.String
m.foldLeft("")(foldFn)
それでは、(文字列、INT)にKVパラメータを変更してみましょう:
scala> val foldFn = (z: String, kv: (String, Int)) => z + kv._2
foldFn: (String, (String, Int)) => java.lang.String = <function2>
scala> m.foldLeft("")(foldFn)
res299: java.lang.String = 12
私はFooの例とは異なり、この場合には地図の「B」値は、関数の定義より優先して、だけのためでありますkvパラメータ私は何を期待しているだろうことは、次のように定義されたfoldLeftを確認することです。私にはより明確になり
foldLeft[C] (z: C)(op: (C, (A, B)) => C): C
を、それはこのように定義されていません。では、メソッドのパラメータがtrait/classパラメータをオーバーライドするときのルールを知っていますか?
何らかの理由で私は投稿後に私の質問に答えを見つけるようだ:) http://stackoverflow.com/questions/8397684/type-parameter-of-minbybf-ab-bimplicit-cmp-orderingb-abしかし、これがいつ発生したのかを知るためのルールがあるかどうかは知りたいです。 – Mike
'foldLeft'が' TraversableOnce'で定義されています。 'A'パラメータは' TraversableOnce'のパラメータであり、 'Map'のパラメータではありません。 –