or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

backported-collections.mdcollection-extensions.mdindex.mdjava-conversion.mdresource-management.mdstring-parsing.mdutility-features.md

backported-collections.mddocs/

0

# Backported Collections

1

2

Complete implementations of Scala 2.13 collection types for use on Scala 2.11 and 2.12. These backported types provide full feature parity with their 2.13 counterparts, enabling forward compatibility and smooth migration paths.

3

4

## Capabilities

5

6

### ArraySeq - Immutable Array-Backed Sequence

7

8

An immutable sequence backed by an Array, providing efficient indexed access and minimal memory overhead.

9

10

```scala { .api }

11

abstract class ArraySeq[+T] extends IndexedSeq[T] {

12

protected[this] def elemTag: ClassTag[T]

13

def length: Int

14

def apply(index: Int): T

15

def unsafeArray: Array[T @uncheckedVariance]

16

override def clone(): ArraySeq[T]

17

}

18

19

object ArraySeq {

20

/**

21

* Create ArraySeq from elements

22

* @param elems Elements to include

23

* @param elemTag ClassTag for element type

24

* @return New ArraySeq containing elements

25

*/

26

def apply[T](elems: T*)(implicit elemTag: ClassTag[T]): ArraySeq[T]

27

28

/**

29

* Create ArraySeq from a collection (available through compat import)

30

* Note: This method is provided via implicit extension from scala.collection.compat._

31

* @param source Source collection

32

* @param elemTag ClassTag for element type

33

* @return New ArraySeq with elements from source

34

*/

35

def from[T](source: TraversableOnce[T])(implicit elemTag: ClassTag[T]): ArraySeq[T]

36

37

/**

38

* Create empty ArraySeq

39

* @return Empty ArraySeq

40

*/

41

def empty[T <: AnyRef]: ArraySeq[T]

42

43

/**

44

* Wrap existing array without copying (unsafe - array must not be mutated)

45

* @param x Source array to wrap

46

* @return ArraySeq wrapping the array

47

*/

48

def unsafeWrapArray[T](x: Array[T]): ArraySeq[T]

49

50

/**

51

* Create builder for ArraySeq

52

* @param elemTag ClassTag for element type

53

* @return Builder for constructing ArraySeq

54

*/

55

def newBuilder[T](implicit elemTag: ClassTag[T]): Builder[T, ArraySeq[T]]

56

57

/**

58

* Pattern matching extractor

59

* @param seq ArraySeq to extract from

60

* @return Some(seq) for pattern matching

61

*/

62

def unapplySeq[T](seq: ArraySeq[T]): Some[ArraySeq[T]]

63

}

64

```

65

66

**Specialized Implementations:**

67

68

ArraySeq provides specialized implementations for primitive types to avoid boxing:

69

70

```scala { .api }

71

final class ofRef[T <: AnyRef](val unsafeArray: Array[T]) extends ArraySeq[T]

72

final class ofByte(val unsafeArray: Array[Byte]) extends ArraySeq[Byte]

73

final class ofShort(val unsafeArray: Array[Short]) extends ArraySeq[Short]

74

final class ofChar(val unsafeArray: Array[Char]) extends ArraySeq[Char]

75

final class ofInt(val unsafeArray: Array[Int]) extends ArraySeq[Int]

76

final class ofLong(val unsafeArray: Array[Long]) extends ArraySeq[Long]

77

final class ofFloat(val unsafeArray: Array[Float]) extends ArraySeq[Float]

78

final class ofDouble(val unsafeArray: Array[Double]) extends ArraySeq[Double]

79

final class ofBoolean(val unsafeArray: Array[Boolean]) extends ArraySeq[Boolean]

80

final class ofUnit(val unsafeArray: Array[Unit]) extends ArraySeq[Unit]

81

```

82

83

**Usage Examples:**

84

85

```scala

86

import scala.collection.compat.immutable.ArraySeq

87

import scala.collection.compat._ // Required for .from method

88

89

// Create from elements

90

val numbers = ArraySeq(1, 2, 3, 4, 5)

91

val strings = ArraySeq("hello", "world")

92

93

// Create from existing collection (requires compat import for .from method)

94

val fromList = ArraySeq.from(List(1, 2, 3))

95

val fromRange = ArraySeq.from(1 to 10)

96

97

// Efficient indexed access

98

val third = numbers(2) // 3

99

val length = numbers.length // 5

100

101

// Wrap existing array (unsafe - don't mutate the source array!)

102

val array = Array(1, 2, 3)

103

val wrapped = ArraySeq.unsafeWrapArray(array)

104

105

// Builder pattern

106

val builder = ArraySeq.newBuilder[Int]

107

builder += 1

108

builder += 2

109

val built = builder.result()

110

111

// Pattern matching

112

ArraySeq(1, 2, 3) match {

113

case ArraySeq(first, rest @ _*) => println(s"First: $first, Rest: $rest")

114

}

115

```

116

117

### LazyList - Lazy Immutable Linked List

118

119

An immutable linked list that evaluates elements lazily with memoization, perfect for infinite sequences and memory-efficient data processing.

120

121

```scala { .api }

122

final class LazyList[+A] extends LinearSeq[A] {

123

/**

124

* Size if known, -1 otherwise (avoids forcing evaluation)

125

* @return Known size or -1

126

*/

127

def knownSize: Int

128

129

/**

130

* Test if LazyList is empty

131

* @return true if empty

132

*/

133

override def isEmpty: Boolean

134

135

/**

136

* Get first element (forces evaluation of head)

137

* @return First element

138

* @throws NoSuchElementException if empty

139

*/

140

override def head: A

141

142

/**

143

* Get remaining elements (forces evaluation of head only)

144

* @return Tail LazyList

145

* @throws UnsupportedOperationException if empty

146

*/

147

override def tail: LazyList[A]

148

149

/**

150

* Force evaluation of all elements

151

* @return This LazyList with all elements evaluated

152

*/

153

def force: this.type

154

155

/**

156

* Lazy concatenation with another collection

157

* @param suffix Collection to append lazily

158

* @return New LazyList with suffix appended

159

*/

160

def lazyAppendedAll[B >: A](suffix: => GenTraversableOnce[B]): LazyList[B]

161

162

/**

163

* Apply side effect while preserving laziness

164

* @param f Side effect function

165

* @return LazyList with side effects applied during traversal

166

*/

167

def tapEach[U](f: A => U): LazyList[A]

168

169

/**

170

* Partition and map simultaneously (lazy evaluation)

171

* @param f Function returning Either for partitioning and transformation

172

* @return Tuple of (left LazyList, right LazyList)

173

*/

174

def partitionMap[A1, A2](f: A => Either[A1, A2]): (LazyList[A1], LazyList[A2])

175

176

/**

177

* Remove duplicates by function (lazy evaluation)

178

* @param f Function to extract comparison key

179

* @return LazyList with duplicates removed

180

*/

181

def distinctBy[B](f: A => B): LazyList[B]

182

}

183

```

184

185

**LazyList Factory Methods:**

186

187

```scala { .api }

188

object LazyList {

189

/**

190

* Empty LazyList

191

* @return Empty LazyList

192

*/

193

def empty[A]: LazyList[A]

194

195

/**

196

* Create LazyList from elements

197

* @param elems Elements to include

198

* @return LazyList containing elements

199

*/

200

def apply[A](elems: A*): LazyList[A]

201

202

/**

203

* Create LazyList from collection

204

* @param coll Source collection

205

* @return LazyList with elements from collection

206

*/

207

def from[A](coll: GenTraversableOnce[A]): LazyList[A]

208

209

/**

210

* Create infinite LazyList by iteration

211

* @param start Starting value (call-by-name)

212

* @param f Function to generate next value

213

* @return Infinite LazyList

214

*/

215

def iterate[A](start: => A)(f: A => A): LazyList[A]

216

217

/**

218

* Create infinite numeric sequence

219

* @param start Starting number

220

* @param step Step size

221

* @return Infinite LazyList of numbers

222

*/

223

def from(start: Int, step: Int): LazyList[Int]

224

225

/**

226

* Create infinite numeric sequence with step 1

227

* @param start Starting number

228

* @return Infinite LazyList of numbers

229

*/

230

def from(start: Int): LazyList[Int]

231

232

/**

233

* Create infinite LazyList repeating element

234

* @param elem Element to repeat (call-by-name)

235

* @return Infinite LazyList of repeated element

236

*/

237

def continually[A](elem: => A): LazyList[A]

238

239

/**

240

* Create LazyList with n copies of element

241

* @param n Number of copies

242

* @param elem Element to repeat (call-by-name)

243

* @return LazyList with n copies

244

*/

245

def fill[A](n: Int)(elem: => A): LazyList[A]

246

247

/**

248

* Create LazyList by tabulation

249

* @param n Number of elements

250

* @param f Function from index to element

251

* @return LazyList created by applying function to indices

252

*/

253

def tabulate[A](n: Int)(f: Int => A): LazyList[A]

254

255

/**

256

* Create LazyList by unfolding from seed value

257

* @param init Initial seed value

258

* @param f Function that produces (element, next seed) or None to stop

259

* @return LazyList created by unfolding

260

*/

261

def unfold[A, S](init: S)(f: S => Option[(A, S)]): LazyList[A]

262

263

/**

264

* Concatenate multiple iterables into LazyList

265

* @param xss Iterables to concatenate

266

* @return LazyList containing all elements

267

*/

268

def concat[A](xss: collection.Iterable[A]*): LazyList[A]

269

}

270

```

271

272

**Cons Operations and Syntax:**

273

274

```scala { .api }

275

/**

276

* Alternative cons construction

277

*/

278

object cons {

279

def unapply[A](xs: LazyList[A]): Option[(A, LazyList[A])]

280

}

281

282

/**

283

* Pattern matching cons extractor

284

*/

285

object #:: {

286

def unapply[A](xs: LazyList[A]): Option[(A, LazyList[A])]

287

}

288

289

/**

290

* Implicit conversion to enable #:: syntax

291

* @param l LazyList (call-by-name)

292

* @return Deferrer for cons operations

293

*/

294

implicit def toDeferrer[A](l: => LazyList[A]): Deferrer[A]

295

296

final class Deferrer[A] {

297

/**

298

* Prepend element to LazyList

299

* @param elem Element to prepend (call-by-name)

300

* @return New LazyList with element prepended

301

*/

302

def #::[B >: A](elem: => B): LazyList[B]

303

304

/**

305

* Prepend LazyList to LazyList

306

* @param prefix LazyList to prepend

307

* @return Combined LazyList

308

*/

309

def #:::[B >: A](prefix: LazyList[B]): LazyList[B]

310

}

311

```

312

313

**Usage Examples:**

314

315

```scala

316

import scala.collection.compat.immutable.LazyList

317

318

// Create finite LazyList

319

val finite = LazyList(1, 2, 3, 4, 5)

320

val fromRange = LazyList.from(1 to 100)

321

322

// Create infinite LazyList

323

val naturals = LazyList.from(1) // 1, 2, 3, 4, ...

324

val evens = LazyList.from(0, 2) // 0, 2, 4, 6, ...

325

val fibonacci = LazyList.iterate((0, 1)) { case (a, b) => (b, a + b) }.map(_._1)

326

327

// Cons syntax

328

val list1 = 1 #:: 2 #:: 3 #:: LazyList.empty

329

val list2 = 0 #:: list1 // Prepend element

330

val list3 = LazyList(-2, -1) #::: list2 // Prepend LazyList

331

332

// Lazy operations (elements computed on demand)

333

val squares = naturals.map(n => n * n)

334

val first10Squares = squares.take(10).toList

335

336

// Pattern matching

337

fibonacci match {

338

case a #:: b #:: rest => println(s"First two: $a, $b")

339

case _ => println("Not enough elements")

340

}

341

342

// Force evaluation

343

val evaluated = LazyList(1, 2, 3).force

344

345

// Infinite data processing

346

val primes = naturals.drop(1).filter(isPrime)

347

val first100Primes = primes.take(100).toList

348

349

// Lazy concatenation

350

val combined = finite.lazyAppendedAll(naturals)

351

352

// Side effects with preserved laziness

353

val logged = naturals.tapEach(n => if (n % 1000 == 0) println(s"Processed $n"))

354

355

// Memory-efficient processing of large datasets

356

def processLargeFile(lines: LazyList[String]): LazyList[ProcessedData] =

357

lines

358

.filter(_.nonEmpty)

359

.map(parseLine)

360

.tapEach(validateData)

361

.distinctBy(_.id)

362

```

363

364

### Version Compatibility

365

366

On Scala 2.13, these types are implemented as type aliases to the standard library implementations:

367

368

```scala { .api }

369

// Scala 2.13 compatibility aliases

370

package scala.collection.compat.immutable {

371

type ArraySeq[+A] = scala.collection.immutable.ArraySeq[A]

372

val ArraySeq = scala.collection.immutable.ArraySeq

373

374

type LazyList[+A] = scala.collection.immutable.LazyList[A]

375

val LazyList = scala.collection.immutable.LazyList

376

}

377

```

378

379

This ensures that code written using the compat library works identically across all Scala versions while providing full implementations for older versions that lack these collection types.