Skip to content

Commit 8798098

Browse files
committed
Add an implementation of BuildFrom for IArray
for use with e.g. Future.sequence, LazyZip, Random.shuffle
1 parent d76d5a2 commit 8798098

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

library/src/scala/collection/BuildFrom.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import scala.annotation.implicitNotFound
1919
import scala.collection.mutable.Builder
2020
import scala.collection.immutable.WrappedString
2121
import scala.reflect.ClassTag
22+
import scala.annotation.experimental
2223

2324
/** Builds a collection of type `C` from elements of type `A` when a source collection of type `From` is available.
2425
* Implicit instances of `BuildFrom` are available for all collection types.
@@ -84,6 +85,15 @@ object BuildFrom extends BuildFromLowPriority1 {
8485
def newBuilder(from: Array[?]): Builder[A, Array[A]] = Factory.arrayFactory[A].newBuilder
8586
}
8687

88+
@experimental
89+
given buildFromIArray[A : ClassTag]: BuildFrom[IArray[Any], A, IArray[A]] =
90+
// IArray[?] is unreducible wildcard, but as IArray is covariant its ok to use IArray[Any] here.
91+
new BuildFrom[IArray[Any], A, IArray[A]]:
92+
def fromSpecific(from: IArray[Any])(it: IterableOnce[A]^): IArray[A] =
93+
// TODO: when IArray factory is added to library, delegate there.
94+
IArray.unsafeFromArray(Factory.arrayFactory[A].fromSpecific(it))
95+
def newBuilder(from: IArray[Any]): Builder[A, IArray[A]] = IArray.newBuilder[A]
96+
8797
implicit def buildFromView[A, B]: BuildFrom[View[A], B, View[B]] =
8898
new BuildFrom[View[A], B, View[B]] {
8999
def fromSpecific(from: View[A])(it: IterableOnce[B]^): View[B]^{it} = View.from(it)

project/MiMaFilters.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ object MiMaFilters {
99
// Additions that require a new minor version of the library
1010
Build.mimaPreviousDottyVersion -> Seq(
1111
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.caps.package#package.freeze"),
12+
// IArray integration with Scala Collections:
13+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.BuildFrom.buildFromIArray"),
1214
),
1315

1416
)

tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ val experimentalDefinitionInLibrary = Set(
9898

9999
// New feature: Erased trait
100100
"scala.compiletime.Erased",
101+
102+
// New API: BuildFrom[IArray[Any], T, IArray[T]]
103+
"scala.collection.BuildFrom$.buildFromIArray",
101104
)
102105

103106

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//> using options -experimental
2+
3+
import scala.collection.BuildFrom
4+
5+
def diffs(ns: IArray[Long]): IArray[Long] =
6+
ns.lazyZip(ns.tail).map((a, b) => b - a)
7+
8+
def diffsB(ns: IArray[Long])(bf: BuildFrom[IArray[Long], Long, IArray[Long]]): IArray[Long] =
9+
ns.lazyZip(ns.tail).map((a, b) => b - a)(using bf)
10+
11+
@main def Test: Unit =
12+
val explicit: BuildFrom[IArray[Long], Long, IArray[Long]] =
13+
scala.collection.BuildFrom.buildFromIArray[Long]
14+
15+
val contextual: BuildFrom[IArray[Long], Long, IArray[Long]] =
16+
summon[BuildFrom[IArray[Long], Long, IArray[Long]]]
17+
18+
val contextualWide: BuildFrom[IArray[Any], Long, IArray[Long]] =
19+
summon[BuildFrom[IArray[Any], Long, IArray[Long]]]
20+
21+
assert(explicit.getClass == contextual.getClass) // check default is same implementation.
22+
assert(explicit.getClass == contextualWide.getClass) // check default is same implementation.
23+
24+
assert(diffs(IArray(1L, 3L, 6L, 10L)).sameElements(IArray(2L, 3L, 4L)))
25+
assert(diffsB(IArray(1L, 3L, 6L, 10L))(contextual).sameElements(IArray(2L, 3L, 4L)))
26+
assert(diffsB(IArray(1L, 3L, 6L, 10L))(contextualWide).sameElements(IArray(2L, 3L, 4L)))

0 commit comments

Comments
 (0)