or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdcapabilities.mdcollections.mdcore-types.mdderivation.mdindex.mdmetaprogramming.mdruntime.mdutilities.md

collections.mddocs/

0

# Immutable Collections

1

2

High-performance immutable arrays with covariant types and comprehensive collection operations, providing JavaScript-optimized implementations of standard collection patterns.

3

4

## Capabilities

5

6

### IArray - Immutable Arrays

7

8

Covariant immutable arrays with complete collection API and primitive specializations.

9

10

```scala { .api }

11

/**

12

* Immutable array with covariant type parameter

13

* Provides O(1) access with immutable semantics

14

*/

15

opaque type IArray[+T] = Array[? <: T]

16

17

object IArray:

18

/** Create empty IArray */

19

def empty[T]: IArray[T]

20

21

/** Create IArray from elements */

22

def apply[T](elems: T*): IArray[T]

23

24

/** Create IArray with repeated element */

25

def fill[T](n: Int)(elem: => T): IArray[T]

26

27

/** Create IArray using index function */

28

def tabulate[T](n: Int)(f: Int => T): IArray[T]

29

30

/** Create IArray with range of integers */

31

def range(start: Int, end: Int): IArray[Int]

32

def range(start: Int, end: Int, step: Int): IArray[Int]

33

34

/** Create IArray from iterable */

35

def from[T](it: IterableOnce[T]): IArray[T]

36

37

/** Concatenate multiple IArrays */

38

def concat[T](arrays: IArray[T]*): IArray[T]

39

40

/**

41

* Extension methods for IArray instances

42

*/

43

extension [T](arr: IArray[T])

44

// Access operations

45

/** Get element at index */

46

def apply(index: Int): T

47

/** Get array length */

48

def length: Int

49

/** Check if array is empty */

50

def isEmpty: Boolean

51

/** Check if array is non-empty */

52

def nonEmpty: Boolean

53

/** Get indices range */

54

def indices: Range

55

56

// Element access

57

/** Get first element (unsafe) */

58

def head: T

59

/** Get first element safely */

60

def headOption: Option[T]

61

/** Get last element (unsafe) */

62

def last: T

63

/** Get last element safely */

64

def lastOption: Option[T]

65

/** Get all elements except first */

66

def tail: IArray[T]

67

/** Get all elements except last */

68

def init: IArray[T]

69

70

// Transformation operations

71

/** Transform each element */

72

def map[U](f: T => U): IArray[U]

73

/** Transform with index */

74

def mapWithIndex[U](f: (T, Int) => U): IArray[U]

75

/** Flat map transformation */

76

def flatMap[U](f: T => IterableOnce[U]): IArray[U]

77

/** Filter elements */

78

def filter(p: T => Boolean): IArray[T]

79

/** Filter with negation */

80

def filterNot(p: T => Boolean): IArray[T]

81

/** Collect partial function results */

82

def collect[U](pf: PartialFunction[T, U]): IArray[U]

83

84

// Slicing operations

85

/** Take first n elements */

86

def take(n: Int): IArray[T]

87

/** Drop first n elements */

88

def drop(n: Int): IArray[T]

89

/** Take while predicate holds */

90

def takeWhile(p: T => Boolean): IArray[T]

91

/** Drop while predicate holds */

92

def dropWhile(p: T => Boolean): IArray[T]

93

/** Take right n elements */

94

def takeRight(n: Int): IArray[T]

95

/** Drop right n elements */

96

def dropRight(n: Int): IArray[T]

97

/** Get slice between indices */

98

def slice(from: Int, until: Int): IArray[T]

99

/** Split at index */

100

def splitAt(n: Int): (IArray[T], IArray[T])

101

102

// Combination operations

103

/** Concatenate with another IArray */

104

def concat[U >: T](that: IArray[U]): IArray[U]

105

def ++[U >: T](that: IArray[U]): IArray[U]

106

/** Prepend element */

107

def prepended[U >: T](elem: U): IArray[U]

108

/** Append element */

109

def appended[U >: T](elem: U): IArray[U]

110

/** Prepend elements */

111

def prependedAll[U >: T](prefix: IterableOnce[U]): IArray[U]

112

/** Append elements */

113

def appendedAll[U >: T](suffix: IterableOnce[U]): IArray[U]

114

115

// Searching operations

116

/** Find element matching predicate */

117

def find(p: T => Boolean): Option[T]

118

/** Check if element exists */

119

def exists(p: T => Boolean): Boolean

120

/** Check if all elements match */

121

def forall(p: T => Boolean): Boolean

122

/** Check if contains element */

123

def contains[U >: T](elem: U): Boolean

124

/** Find index of element */

125

def indexOf[U >: T](elem: U): Int

126

def indexOf[U >: T](elem: U, from: Int): Int

127

/** Find last index of element */

128

def lastIndexOf[U >: T](elem: U): Int

129

def lastIndexOf[U >: T](elem: U, end: Int): Int

130

/** Find index where predicate holds */

131

def indexWhere(p: T => Boolean): Int

132

def indexWhere(p: T => Boolean, from: Int): Int

133

134

// Sorting operations

135

/** Sort elements */

136

def sorted[U >: T](using Ordering[U]): IArray[U]

137

/** Sort by key */

138

def sortBy[U](f: T => U)(using Ordering[U]): IArray[T]

139

/** Sort with custom comparator */

140

def sortWith(lt: (T, T) => Boolean): IArray[T]

141

142

// Grouping operations

143

/** Remove duplicate elements */

144

def distinct: IArray[T]

145

/** Remove duplicates by key */

146

def distinctBy[U](f: T => U): IArray[T]

147

/** Group by key */

148

def groupBy[K](f: T => K): Map[K, IArray[T]]

149

/** Group consecutive equal elements */

150

def groupMap[K, V](key: T => K)(f: T => V): Map[K, IArray[V]]

151

/** Partition by predicate */

152

def partition(p: T => Boolean): (IArray[T], IArray[T])

153

/** Span while predicate holds */

154

def span(p: T => Boolean): (IArray[T], IArray[T])

155

156

// Aggregation operations

157

/** Fold left */

158

def foldLeft[U](z: U)(op: (U, T) => U): U

159

/** Fold right */

160

def foldRight[U](z: U)(op: (T, U) => U): U

161

/** Reduce left */

162

def reduceLeft[U >: T](op: (U, T) => U): U

163

/** Reduce right */

164

def reduceRight[U >: T](op: (T, U) => U): U

165

/** Reduce with option */

166

def reduceLeftOption[U >: T](op: (U, T) => U): Option[U]

167

def reduceRightOption[U >: T](op: (T, U) => U): Option[U]

168

/** Aggregate/combine */

169

def aggregate[U](z: => U)(seqop: (U, T) => U, combop: (U, U) => U): U

170

171

// Conversion operations

172

/** Convert to Array */

173

def toArray[U >: T : ClassTag]: Array[U]

174

/** Convert to List */

175

def toList: List[T]

176

/** Convert to Vector */

177

def toVector: Vector[T]

178

/** Convert to Set */

179

def toSet: Set[T]

180

/** Convert to Map with indices */

181

def toMap[K, V](using ev: T <:< (K, V)): Map[K, V]

182

/** Convert to mutable buffer */

183

def toBuffer: mutable.Buffer[T]

184

185

// Zipping operations

186

/** Zip with another collection */

187

def zip[U](that: IArray[U]): IArray[(T, U)]

188

/** Zip with indices */

189

def zipWithIndex: IArray[(T, Int)]

190

/** Zip all with filler values */

191

def zipAll[U, V >: T](that: IArray[U], thisElem: V, thatElem: U): IArray[(V, U)]

192

193

// Utility operations

194

/** Apply side effect to each element */

195

def foreach[U](f: T => U): Unit

196

/** Reverse array order */

197

def reverse: IArray[T]

198

/** Get string representation */

199

def mkString: String

200

def mkString(sep: String): String

201

def mkString(start: String, sep: String, end: String): String

202

/** Get element count */

203

def count(p: T => Boolean): Int

204

/** Check if corresponds to another collection */

205

def corresponds[U](that: IterableOnce[U])(p: (T, U) => Boolean): Boolean

206

```

207

208

**Usage Examples:**

209

210

```scala

211

import scala.IArray

212

213

// Creating IArrays

214

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

215

val empty = IArray.empty[String]

216

val filled = IArray.fill(3)("default")

217

val computed = IArray.tabulate(5)(i => i * i)

218

val range = IArray.range(1, 10)

219

220

// Basic operations

221

println(numbers.length) // 5

222

println(numbers.head) // 1

223

println(numbers.last) // 5

224

println(numbers.isEmpty) // false

225

226

// Transformations

227

val doubled = numbers.map(_ * 2)

228

val evens = numbers.filter(_ % 2 == 0)

229

val squares = numbers.map(x => x * x)

230

231

// Slicing

232

val first3 = numbers.take(3) // IArray(1, 2, 3)

233

val without2 = numbers.drop(2) // IArray(3, 4, 5)

234

val middle = numbers.slice(1, 4) // IArray(2, 3, 4)

235

236

// Searching

237

val found = numbers.find(_ > 3) // Some(4)

238

val index = numbers.indexOf(3) // 2

239

val contains4 = numbers.contains(4) // true

240

241

// Sorting

242

val names = IArray("Charlie", "Alice", "Bob")

243

val sorted = names.sorted // IArray("Alice", "Bob", "Charlie")

244

val byLength = names.sortBy(_.length) // IArray("Bob", "Alice", "Charlie")

245

246

// Aggregation

247

val sum = numbers.foldLeft(0)(_ + _) // 15

248

val max = numbers.reduceLeft(_ max _) // 5

249

val product = numbers.reduce(_ * _) // 120

250

251

// Grouping

252

val data = IArray("apple", "banana", "apricot", "cherry")

253

val byFirstLetter = data.groupBy(_.head)

254

// Map('a' -> IArray("apple", "apricot"), 'b' -> IArray("banana"), 'c' -> IArray("cherry"))

255

256

// Combinations

257

val moreNumbers = IArray(6, 7, 8)

258

val combined = numbers ++ moreNumbers // IArray(1, 2, 3, 4, 5, 6, 7, 8)

259

val withZero = numbers.prepended(0) // IArray(0, 1, 2, 3, 4, 5)

260

261

// Zipping

262

val letters = IArray("a", "b", "c", "d", "e")

263

val pairs = numbers.zip(letters) // IArray((1,"a"), (2,"b"), (3,"c"), (4,"d"), (5,"e"))

264

val indexed = numbers.zipWithIndex // IArray((1,0), (2,1), (3,2), (4,3), (5,4))

265

266

// Conversions

267

val asList = numbers.toList

268

val asVector = numbers.toVector

269

val asArray = numbers.toArray

270

val asSet = numbers.toSet

271

```

272

273

### Specialized IArray Types

274

275

IArray provides specialized implementations for primitive types for better performance.

276

277

```scala { .api }

278

// Specialized factory methods

279

object IArray:

280

/** Create specialized boolean array */

281

def ofBoolean(elems: Boolean*): IArray[Boolean]

282

/** Create specialized byte array */

283

def ofByte(elems: Byte*): IArray[Byte]

284

/** Create specialized short array */

285

def ofShort(elems: Short*): IArray[Short]

286

/** Create specialized char array */

287

def ofChar(elems: Char*): IArray[Char]

288

/** Create specialized int array */

289

def ofInt(elems: Int*): IArray[Int]

290

/** Create specialized long array */

291

def ofLong(elems: Long*): IArray[Long]

292

/** Create specialized float array */

293

def ofFloat(elems: Float*): IArray[Float]

294

/** Create specialized double array */

295

def ofDouble(elems: Double*): IArray[Double]

296

```

297

298

**Usage Examples:**

299

300

```scala

301

// Specialized arrays for better performance

302

val ints = IArray.ofInt(1, 2, 3, 4, 5)

303

val doubles = IArray.ofDouble(1.0, 2.5, 3.14)

304

val booleans = IArray.ofBoolean(true, false, true)

305

306

// All operations work the same

307

val doubled = ints.map(_ * 2)

308

val filtered = doubles.filter(_ > 2.0)

309

val count = booleans.count(identity)

310

```

311

312

### Multi-dimensional Arrays

313

314

Support for creating and working with multi-dimensional immutable arrays.

315

316

```scala { .api }

317

object IArray:

318

/** Create 2D array */

319

def ofDim[T](dim1: Int, dim2: Int): IArray[IArray[T]]

320

/** Create 3D array */

321

def ofDim[T](dim1: Int, dim2: Int, dim3: Int): IArray[IArray[IArray[T]]]

322

323

/** Fill 2D array */

324

def fill[T](dim1: Int, dim2: Int)(elem: => T): IArray[IArray[T]]

325

/** Fill 3D array */

326

def fill[T](dim1: Int, dim2: Int, dim3: Int)(elem: => T): IArray[IArray[IArray[T]]]

327

328

/** Tabulate 2D array */

329

def tabulate[T](dim1: Int, dim2: Int)(f: (Int, Int) => T): IArray[IArray[T]]

330

/** Tabulate 3D array */

331

def tabulate[T](dim1: Int, dim2: Int, dim3: Int)(f: (Int, Int, Int) => T): IArray[IArray[IArray[T]]]

332

```

333

334

**Usage Examples:**

335

336

```scala

337

// 2D matrix

338

val matrix = IArray.tabulate(3, 3)((i, j) => i * 3 + j)

339

// IArray(IArray(0, 1, 2), IArray(3, 4, 5), IArray(6, 7, 8))

340

341

// Access elements

342

val element = matrix(1)(2) // 5

343

344

// 3D tensor

345

val tensor = IArray.fill(2, 2, 2)(0)

346

```

347

348

## Types

349

350

```scala { .api }

351

// Core immutable array type

352

opaque type IArray[+T] = Array[? <: T]

353

354

// Companion object with factory methods

355

object IArray:

356

def empty[T]: IArray[T]

357

def apply[T](elems: T*): IArray[T]

358

def fill[T](n: Int)(elem: => T): IArray[T]

359

def tabulate[T](n: Int)(f: Int => T): IArray[T]

360

def range(start: Int, end: Int): IArray[Int]

361

def range(start: Int, end: Int, step: Int): IArray[Int]

362

def from[T](it: IterableOnce[T]): IArray[T]

363

def concat[T](arrays: IArray[T]*): IArray[T]

364

365

// Specialized factory methods

366

def ofBoolean(elems: Boolean*): IArray[Boolean]

367

def ofByte(elems: Byte*): IArray[Byte]

368

def ofShort(elems: Short*): IArray[Short]

369

def ofChar(elems: Char*): IArray[Char]

370

def ofInt(elems: Int*): IArray[Int]

371

def ofLong(elems: Long*): IArray[Long]

372

def ofFloat(elems: Float*): IArray[Float]

373

def ofDouble(elems: Double*): IArray[Double]

374

375

// Multi-dimensional arrays

376

def ofDim[T](dim1: Int, dim2: Int): IArray[IArray[T]]

377

def ofDim[T](dim1: Int, dim2: Int, dim3: Int): IArray[IArray[IArray[T]]]

378

```