Ich denke, dass Sie in eine Beschränkung der Art Rückschluss-System laufen. Um etwas Licht in diese, mal schauen, was passiert, wenn wir diese ein wenig neu definieren eine nützlichere Ausgabe zu erhalten:
class Bar[F[_], A](x: F[A], y: F[A]) {}
res0: Bar[List,Int] = [email protected]
new Bar(List(1,2,3), List(1))
res1: Bar[Any,Int] = [email protected]
new Bar(List(1), 1)
res2: Bar[Any,Int] = [email protected]
new Bar(List(1), Some(1))
<console>:12: error: inferred kinds of the type arguments (Product with java.io.Serializable,Int) do not conform to the expected kinds of the type parameters (type F,type A) in class Bar.
Product with java.io.Serializable's type parameters do not match type F's expected parameters:
<refinement of Product with java.io.Serializable> has no type parameters, but type F has one
new Bar(List(1), Some(1))
^
<console>:12: error: type mismatch;
found : List[Int]
required: F[A]
new Bar(List(1), Some(1))
^
<console>:12: error: type mismatch;
found : Some[Int]
required: F[A]
new Bar(List(1), Some(1))
Im ersten Beispiel haben wir eine Bar[List, Int]
, die durchaus Sinn macht, passierten wir in zwei List[Int]
.
In der zweiten und dritten haben wir eine Bar[Any, Int]
. Hier wird es komisch. Denken Sie daran, dass Any
das übergeordnete Element von beiden AnyVal
(die Eltern von Scala Äquivalenten von Java-Primitiven) und AnyRef
(das Scala-Äquivalent von Java-Objekt) (siehe Scala Documentation für weitere Erklärung).
Scala Typinferenz hat entschieden, dass diese Bar
‚s Konstruktor Any
für F
annehmen sollte, und Int
für A
. Als Any
ist in der Tat ein Elternteil von List
und Int
, das ist in Ordnung. Die List
ist in der Tat als [Int]
parametriert, so dass es in Ordnung ist. Was komisch ist, ist, dass Scala okay ist zu sagen, dass der Int
auch vom Typ Any[Int]
ist. Ich habe keine gute Erklärung für diesen Teil.
Mit dem letzten, das ist, wo ich ehrlich verwirrt bin, und ich muss mich fragen, ob das ein Fehler ist. Aus irgendeinem Grund, obwohl beide List
und Some
Kinder von Any
sind, und beide mit Int
parametrisiert sind, erlaubt es es nicht. Ich fürchte, ich bin nicht gut in die Feinheiten des Compilers Inferenzmethoden versiert, aber für das, was es wert ist, explizit die Parameter angeben, funktioniert:
new Bar[Any,Int](List(1), Some(1))
res14: Bar[Any,Int] = [email protected]
Für mich, dass die Typinferenz System schlägt nur kann‘ t richtig die Typen ableiten, oder es sind Inferenztypen, die nicht korrekt sind.
Sowohl 'Any' und' Nothing' ist Art polymorphe siehe z.B. [SI-9248] (https://issues.scala-lang.org/browse/SI-9248). –
btw 'bar (1, Liste (1))' compiliert nicht in '2.9', sondern in' 2.10'. – dmitry