Skip to content

Commit 1841b9d

Browse files
committed
add unfold method
1 parent 65cf59e commit 1841b9d

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

build.sbt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ lazy val compat = new MultiScalaCrossProject(
8787
import com.typesafe.tools.mima.core._
8888
import com.typesafe.tools.mima.core.ProblemFilters._
8989
Seq(
90+
// https://github.com/scala/scala-collection-compat/pull/611
91+
exclude[MissingClassProblem]("scala.collection.compat.GenericCompanionExtensionMethods"),
92+
exclude[MissingClassProblem]("scala.collection.compat.GenericCompanionExtensionMethods$"),
93+
exclude[DirectMissingMethodProblem]("scala.collection.compat.package.toGenericCompanionExtensionMethods"),
9094
exclude[ReversedMissingMethodProblem](
9195
"scala.collection.compat.PackageShared.*"
9296
), // it's package-private

compat/src/main/scala-2.11_2.12/scala/collection/compat/PackageShared.scala

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
package scala.collection.compat
1414

15-
import scala.annotation.nowarn
15+
import scala.annotation.{nowarn, tailrec}
1616
import scala.collection.generic._
1717
import scala.reflect.ClassTag
1818
import scala.collection.{
@@ -249,6 +249,10 @@ private[compat] trait PackageShared {
249249
fact.apply(source.toSeq: _*)
250250
}
251251

252+
implicit def toGenericCompanionExtensionMethods[CC[X] <: GenTraversable[X]](
253+
companion: GenericCompanion[CC]
254+
): GenericCompanionExtensionMethods[CC] = new GenericCompanionExtensionMethods[CC](companion)
255+
252256
implicit class MapFactoryExtensionMethods[CC[A, B] <: Map[A, B] with MapLike[A, B, CC[A, B]]](
253257
private val fact: MapFactory[CC]) {
254258
def from[K, V](source: TraversableOnce[(K, V)]): CC[K, V] =
@@ -663,3 +667,25 @@ class OptionCompanionExtensionMethods(private val fact: Option.type) extends Any
663667

664668
@inline def unless[A](cond: Boolean)(a: => A): Option[A] = when(!cond)(a)
665669
}
670+
671+
class GenericCompanionExtensionMethods[CC[X] <: GenTraversable[X]](
672+
private val companion: GenericCompanion[CC]) extends AnyVal {
673+
def unfold[A, S](init: S)(f: S => Option[(A, S)])(
674+
implicit cbf: CanBuildFrom[CC[A], A, CC[A]]
675+
): CC[A] = {
676+
val builder = cbf()
677+
678+
@tailrec
679+
def loop(s1: S): Unit = {
680+
f(s1) match {
681+
case Some((a, s2)) =>
682+
builder += a
683+
loop(s2)
684+
case None =>
685+
}
686+
}
687+
688+
loop(init)
689+
builder.result()
690+
}
691+
}

compat/src/test/scala/test/scala/collection/CollectionTest.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,30 @@ class CollectionTest {
193193
assertEquals(List(3, 1, 2).distinctBy(_ % 2 == 0), List(3, 2))
194194
assertEquals(List.empty[Int].distinctBy(_ % 2 == 0), List.empty)
195195
}
196+
197+
@Test
198+
def testUnfold(): Unit = {
199+
def typed[A](x: A): Unit = ()
200+
201+
val list = List.unfold(1)(x => if (x <= 5) Some((x.toString, x + 1)) else None)
202+
typed[List[String]](list)
203+
assertEquals(list, List("1", "2", "3", "4", "5"))
204+
205+
val vector = Vector.unfold(1)(x => if (x <= 100) Some((x, x * 3)) else None)
206+
typed[Vector[Int]](vector)
207+
assertEquals(vector, Vector(1, 3, 9, 27, 81))
208+
209+
val seq = collection.Seq.unfold(1L)(x => if (x <= 10L) Some(x, x + 2L) else None)
210+
typed[collection.Seq[Long]](seq)
211+
assertEquals(seq, collection.Seq(1L, 3L, 5L, 7L, 9L))
212+
213+
val iterable = Iterable.unfold(4)(x => if (x > 0) Some(("a" * x, x - 1)) else None)
214+
typed[Iterable[String]](iterable)
215+
assertEquals(iterable, Iterable("aaaa", "aaa", "aa", "a"))
216+
217+
val arrayBuffer =
218+
collection.mutable.ArrayBuffer.unfold(1)(x => if (x < 3) Some((x, x + 1)) else None)
219+
typed[collection.mutable.ArrayBuffer[Int]](arrayBuffer)
220+
assertEquals(arrayBuffer, collection.mutable.ArrayBuffer(1, 2))
221+
}
196222
}

0 commit comments

Comments
 (0)