Vì lý do nào đó, nhập suy luận cho số shuffle
sẽ tạo ra một kết quả khác nhau cho số Inclusive
trái ngược với Range
.
Lý do toSeq
kết quả trong Range
là định nghĩa của nó ngây thơ thu hẹp loại:
override def toSeq = this
Có một vấn đề mở để suy ra kiểu kết quả của phương pháp ghi đè để thay thế.
Hiển thị rằng REPL là không nói dối:
scala> import util.Random.shuffle
import util.Random.shuffle
scala> val x = 1 to 10
x: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val y = x.toSeq
y: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val z: Range = x
z: Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> shuffle(x)
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 5, 2, 10, 9, 6, 3, 7, 4, 8)
scala> shuffle(y)
<console>:11: error: Cannot construct a collection of type scala.collection.AbstractSeq[Int] with elements of type Int based on a collection of type scala.collection.AbstractSeq[Int].
shuffle(y)
^
Snipping để xem những gì đã được suy ra và những gì tiềm ẩn đã được sử dụng:
scala> :replay -Xprint:typer
Replaying: shuffle(x)
private[this] val res0: scala.collection.immutable.IndexedSeq[Int] = scala.util.Random.shuffle[Int, scala.collection.immutable.IndexedSeq]($line5.$read.$iw.$iw.x)(immutable.this.IndexedSeq.canBuildFrom[Int]);
scala> shuffle(y)
private[this] val <res1: error>: <error> = scala.util.Random.shuffle[Int, scala.collection.AbstractSeq]($line6.$read.$iw.$iw.y)();
thay vì những gì bạn hy vọng:
scala> shuffle[Int, collection.immutable.IndexedSeq](z)
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(6, 5, 3, 8, 4, 1, 2, 10, 7, 9)
Với -Ytyper-debug
, có thêm một tham số kiểu A
có vẻ như để cho nó bắt đầu ed cho Inclusive
, nhưng tôi không biết điều đó đến từ đâu.
| | | | |-- x BYVALmode-EXPRmode-POLYmode (site: value res3 in $iw)
| | | | | \-> scala.collection.immutable.Range.Inclusive
| | | | solving for (T: ?T, CC: ?CC)
| | | | solving for (A: ?A)
| | | | [adapt] [A]=> scala.collection.generic.CanBuildFrom[scala.collect... adapted to [A]=> scala.collection.generic.CanBuildFrom[scala.collect... based on pt scala.collection.generic.CanBuildFrom[scala.collection.immutable.IndexedSeq[Int],Int,scala.collection.immutable.IndexedSeq[Int]]
| | | | |-- [T, CC[X] <: TraversableOnce[X]](xs: CC[T])(implicit bf: ... EXPRmode (site: value res3 in $iw)
| | | | | \-> scala.collection.immutable.IndexedSeq[Int]
| | | | [adapt] [T, CC[X] <: TraversableOnce[X]](xs: CC[T])(implicit bf: ... adapted to [T, CC[X] <: TraversableOnce[X]](xs: CC[T])(implicit bf: ...
| | | | \-> scala.collection.immutable.IndexedSeq[Int]
Đó có phải là lỗi hoặc hành vi không?
Làm cho nó đơn giản:
scala> import language.higherKinds, collection.TraversableOnce, collection.generic.CanBuildFrom
import language.higherKinds
import collection.TraversableOnce
import collection.generic.CanBuildFrom
scala> def f[T, CC[X] <: TraversableOnce[X]](xs: CC[T])(implicit cbf: CanBuildFrom[CC[T],T,CC[T]]): CC[T] = null.asInstanceOf[CC[T]]
f: [T, CC[X] <: scala.collection.TraversableOnce[X]](xs: CC[T])(implicit cbf: scala.collection.generic.CanBuildFrom[CC[T],T,CC[T]])CC[T]
scala> f(1 to 10)
res0: scala.collection.immutable.IndexedSeq[Int] = null
scala> f(1 until 10)
<console>:12: error: Cannot construct a collection of type scala.collection.AbstractSeq[Int] with elements of type Int based on a collection of type scala.collection.AbstractSeq[Int].
f(1 until 10)
^
https://gitter.im/scala/scala?at=554d5ab5675c1d50549ec0f1 được cho là mang tính thể hiện rõ ràng hơn về mặt typography. –