Paradoxerweise ist die erste Version funktioniert, weil subsets
in der Anwendung subsets(2)
ist, wie es war, mehrdeutiger als ohne parens.
Da das Verfahren überlastet ist, in der Anwendung, die Compiler Pausen für das Ergebnis der B
toSet
zu lösen, und entscheidet, dass B
Int
ist. So weiß es, welcher Param-Typ für die map
erwartet wird.
In der Version ohne Parens ist die Methode mit einer Parameterliste kein Kandidat, da eta-expansion nicht ausgelöst wird. Wenn es also die map
-Anwendung eingibt, hat es keine Rückschlüsse auf B
gezogen, die der Eingabetyp für die Zuordnungsfunktion ist.
Die einfache Lösung ist es zu sagen, B
ableiten:
trait Test {
def f1 = List(1, 2, 3).to[Set].subsets.map(_.toList) // instead of .toSet
def f2 = List(1, 2, 3).toSet.subsets(2).map(_.toList)
}
Der Ausgang des -Ytyper-debug
auf dem ursprünglichen Code zeigt, wie die Überladungsauflösung Typinferenz gooses:
| | | | | | \-> => Iterator[scala.collection.immutable.Set[B]] <and> (len: Int)Iterator[scala.collection.immutable.Set[B]]
| | | | | solving for (B: ?B)
| | | | | |-- 2 : pt=Int BYVALmode-EXPRmode-POLYmode (silent: method f2 in Test)
| | | | | | \-> Int(2)
| | | | | solving for (B: ?B)
| | | | | \-> Iterator[scala.collection.immutable.Set[Int]]
Eine andere Lösung ist zu gehen durch eine Erweiterungsmethode:
scala> implicit class ss[A](val s: Set[A]) { def ss(n: Int) = s subsets n ; def ss = s.subsets }
defined class ss
scala> List(1, 2, 3).toSet.ss.map(_.toList)
res1: Iterator[List[Int]] = non-empty iterator
Mal sehen, ob sie die Bibliothek ändern nehmen werden:
https://github.com/scala/scala/pull/4270
Ich würde vermuten, dass die '.subsets' mehr mehrdeutig ist (es eine partielle Anwendung der Version sein könnte, das ein Argument), so Art Schlussfolgerung funktioniert weniger gut. In jedem Fall können Sie es kompilieren, indem Sie tun, was der Compiler Ihnen sagt und einen expliziten Typ bereitstellt: 'List (1, 2, 3) .toSetSets.map {x: Set [Int] => x.toList}' – lmm
Die beiden Methoden haben jedoch dieselbe Rückgabesignatur wie in 2.10.4 scaladoc: 'def Untergruppen: Iterator [Set [A]]', 'Def Subsets (len: Int): Iterator [Set [A]]' Also sollte es keinen Unterschied geben, soweit es Typen betrifft , Recht? – the21st
Ist es nicht eine Inkonsistenz in Scala, dass diese Methoden zusammen erlaubt sind, während eine Methode 'def Subsets (i: Int) (d: Double): Iterator [Set [A]]' einen 'mehrdeutigen Verweis auf überladene Definition' verursachen würde Error? –