or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

collection-extensions.mderror-handling.mdindex.mdoptional-values.mdpartial-results.mdproduct-types.mdraise-dsl.mdsafe-collections.mdutility-functions.md

collection-extensions.mddocs/

0

# Collection Extensions

1

2

Arrow Core provides extensive extension functions for Iterable, Sequence, and Map collections, adding functional programming capabilities, error handling patterns, and advanced collection operations.

3

4

## Iterable Extensions

5

6

### Multi-Argument Zip Operations

7

8

```kotlin { .api }

9

// Zip 3 iterables

10

fun <A, B, C, D> Iterable<A>.zip(

11

b: Iterable<B>,

12

c: Iterable<C>,

13

transform: (A, B, C) -> D

14

): List<D>

15

16

// Similar patterns for 4-11 parameters

17

fun <A, B, C, D, E, F> Iterable<A>.zip(

18

b: Iterable<B>,

19

c: Iterable<C>,

20

d: Iterable<D>,

21

e: Iterable<E>,

22

transform: (A, B, C, D, E) -> F

23

): List<F>

24

25

// ... up to 11-parameter zip functions

26

```

27

28

### Error Accumulation Operations

29

30

```kotlin { .api }

31

// Error accumulation with custom combine function

32

fun <Error, A, B> Iterable<A>.mapOrAccumulate(

33

combine: (Error, Error) -> Error,

34

transform: RaiseAccumulate<Error>.(A) -> B

35

): Either<Error, List<B>>

36

37

// Error accumulation with NonEmptyList errors

38

fun <Error, A, B> Iterable<A>.mapOrAccumulate(

39

transform: RaiseAccumulate<Error>.(A) -> B

40

): Either<NonEmptyList<Error>, List<B>>

41

```

42

43

### Padding and Alignment Operations

44

45

```kotlin { .api }

46

// Pad zip - handles different lengths

47

fun <A, B> Iterable<A>.padZip(other: Iterable<B>): List<Pair<A?, B?>>

48

fun <A, B> Iterable<A>.leftPadZip(other: Iterable<B>): List<Pair<A?, B>>

49

fun <A, B> Iterable<A>.rightPadZip(other: Iterable<B>): List<Pair<A, B?>>

50

51

// Align with Ior for handling missing values

52

fun <A, B> Iterable<A>.align(b: Iterable<B>): List<Ior<A, B>>

53

```

54

55

### Option-Based Safe Operations

56

57

```kotlin { .api }

58

// Safe element access

59

fun <T> Iterable<T>.firstOrNone(): Option<T>

60

fun <T> Iterable<T>.lastOrNone(): Option<T>

61

fun <T> Iterable<T>.singleOrNone(): Option<T>

62

fun <T> Iterable<T>.elementAtOrNone(index: Int): Option<T>

63

```

64

65

### Collection Manipulation

66

67

```kotlin { .api }

68

// Split into tail and last element

69

fun <A> Iterable<A>.split(): Pair<List<A>, A>?

70

71

// Get tail (all but first)

72

fun <A> Iterable<A>.tail(): List<A>

73

74

// Interleave two iterables

75

fun <A> Iterable<A>.interleave(other: Iterable<A>): List<A>

76

77

// Unweave - flatten nested structures

78

fun <A, B> Iterable<A>.unweave(ffa: (A) -> Iterable<B>): List<B>

79

```

80

81

### Either and Ior Operations

82

83

```kotlin { .api }

84

// Separate Either values into left and right lists

85

fun <A, B> Iterable<Either<A, B>>.separateEither(): Pair<List<A>, List<B>>

86

87

// Separate Ior values

88

fun <A, B> Iterable<Ior<A, B>>.separateIor(): Pair<List<A>, List<B>>

89

fun <A, B> Iterable<Ior<A, B>>.unalign(): Pair<List<A?>, List<B?>>

90

```

91

92

### Reduction Operations

93

94

```kotlin { .api }

95

// Safe reduction with nullable result

96

fun <A, B> Iterable<A>.reduceOrNull(

97

initial: (A) -> B,

98

operation: (acc: B, A) -> B

99

): B?

100

```

101

102

## Sequence Extensions

103

104

### Multi-Argument Zip Operations

105

106

```kotlin { .api }

107

// Zip 3 sequences

108

fun <A, B, C, D> Sequence<A>.zip(

109

b: Sequence<B>,

110

c: Sequence<C>,

111

transform: (A, B, C) -> D

112

): Sequence<D>

113

114

// Similar patterns for 4-10 parameters

115

fun <A, B, C, D, E, F> Sequence<A>.zip(

116

b: Sequence<B>,

117

c: Sequence<C>,

118

d: Sequence<D>,

119

e: Sequence<E>,

120

transform: (A, B, C, D, E) -> F

121

): Sequence<F>

122

123

// ... up to 10-parameter zip functions

124

```

125

126

### Alignment and Padding

127

128

```kotlin { .api }

129

// Align sequences with Ior

130

fun <A, B> Sequence<A>.align(other: Sequence<B>): Sequence<Ior<A, B>>

131

132

// Pad zip operations

133

fun <A, B> Sequence<A>.padZip(other: Sequence<B>): Sequence<Pair<A?, B?>>

134

fun <A, B> Sequence<A>.leftPadZip(other: Sequence<B>): Sequence<Pair<A?, B>>

135

fun <A, B> Sequence<A>.rightPadZip(other: Sequence<B>): Sequence<Pair<A, B?>>

136

```

137

138

### Sequence Manipulation

139

140

```kotlin { .api }

141

// Interleave sequences

142

fun <A> Sequence<A>.interleave(other: Sequence<A>): Sequence<A>

143

144

// Split sequence

145

fun <A> Sequence<A>.split(): Pair<Sequence<A>, A>?

146

147

// Get tail

148

fun <A> Sequence<A>.tail(): Sequence<A>

149

150

// Unweave nested sequences

151

fun <A, B> Sequence<A>.unweave(ffa: (A) -> Sequence<B>): Sequence<B>

152

```

153

154

### Specialized Operations

155

156

```kotlin { .api }

157

// Generate multiple sequences

158

fun <A> Sequence<A>.many(): Sequence<Sequence<A>>

159

160

// Single-element sequence

161

fun <A> Sequence<A>.once(): Sequence<A>

162

163

// Align with combining function

164

fun <A> Sequence<A>.salign(other: Sequence<A>, combine: (A, A) -> A): Sequence<A>

165

```

166

167

### Either and Option Operations

168

169

```kotlin { .api }

170

// Separate Either sequences

171

fun <A, B> Sequence<Either<A, B>>.separateEither(): Pair<List<A>, List<B>>

172

173

// Unalign Ior sequences

174

fun <A, B> Sequence<Ior<A, B>>.unalign(): Pair<Sequence<A>, Sequence<B>>

175

176

// Filter Option sequences

177

fun <A> Sequence<Option<A>>.filterOption(): Sequence<A>

178

```

179

180

## Map Extensions

181

182

### Multi-Argument Zip Operations

183

184

```kotlin { .api }

185

// Zip two maps

186

fun <K, A, B> Map<K, A>.zip(other: Map<K, B>): Map<K, Pair<A, B>>

187

188

// Zip with transform function

189

fun <K, A, B, C> Map<K, A>.zip(

190

other: Map<K, B>,

191

transform: (K, A, B) -> C

192

): Map<K, C>

193

194

// Multi-argument zip (3-11 parameters)

195

fun <K, A, B, C, D, E> Map<K, A>.zip(

196

b: Map<K, B>,

197

c: Map<K, C>,

198

d: Map<K, D>,

199

transform: (K, A, B, C, D) -> E

200

): Map<K, E>

201

202

// ... up to 11-parameter zip functions

203

```

204

205

### Value Transformation

206

207

```kotlin { .api }

208

// Error accumulation on map values

209

fun <K, E, A, B> Map<K, A>.mapValuesOrAccumulate(

210

combine: (E, E) -> E,

211

transform: RaiseAccumulate<E>.(Map.Entry<K, A>) -> B

212

): Either<E, Map<K, B>>

213

214

// FlatMap on values

215

fun <K, A, B> Map<K, A>.flatMapValues(

216

f: (Map.Entry<K, A>) -> Map<K, B>

217

): Map<K, B>

218

```

219

220

### Filtering Operations

221

222

```kotlin { .api }

223

// Filter Option values

224

fun <K, A> Map<K, Option<A>>.filterOption(): Map<K, A>

225

226

// Filter by instance type

227

fun <K, R> Map<K, *>.filterIsInstance(): Map<K, R>

228

```

229

230

### Alignment and Padding

231

232

```kotlin { .api }

233

// Align maps with Ior

234

fun <K, A, B> Map<K, A>.align(other: Map<K, B>): Map<K, Ior<A, B>>

235

236

// Pad zip maps

237

fun <K, A, B> Map<K, A>.padZip(other: Map<K, B>): Map<K, Pair<A?, B?>>

238

239

// Align with combining function

240

fun <K, A> Map<K, A>.salign(other: Map<K, A>, combine: (A, A) -> A): Map<K, A>

241

```

242

243

### Unzipping Operations

244

245

```kotlin { .api }

246

// Unzip pairs

247

fun <K, A, B> Map<K, Pair<A, B>>.unzip(): Pair<Map<K, A>, Map<K, B>>

248

249

// Unalign Ior values

250

fun <K, A, B> Map<K, Ior<A, B>>.unalign(): Pair<Map<K, A>, Map<K, B>>

251

```

252

253

### Safe Access and Combination

254

255

```kotlin { .api }

256

// Safe get with Option

257

fun <K, V> Map<K, V>.getOrNone(key: K): Option<V>

258

259

// Combine maps with combining function

260

fun <K, A> Map<K, A>.combine(other: Map<K, A>, combine: (A, A) -> A): Map<K, A>

261

```

262

263

## Usage Examples

264

265

### Multi-Argument Zip

266

267

```kotlin

268

import arrow.core.*

269

270

// Zip multiple iterables

271

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

272

val ages = listOf(25, 30, 35)

273

val cities = listOf("NYC", "SF", "LA")

274

275

val people = names.zip(ages, cities) { name, age, city ->

276

"Person(name=$name, age=$age, city=$city)"

277

}

278

// Result: ["Person(name=Alice, age=25, city=NYC)", ...]

279

```

280

281

### Error Accumulation

282

283

```kotlin

284

import arrow.core.*

285

import arrow.core.raise.*

286

287

data class ValidationError(val field: String, val message: String)

288

289

fun Raise<ValidationError>.validateAge(age: Int): Int {

290

ensure(age >= 0) { ValidationError("age", "Cannot be negative") }

291

ensure(age <= 150) { ValidationError("age", "Unrealistic age") }

292

return age

293

}

294

295

val ages = listOf(25, -5, 200, 30)

296

val validatedAges = ages.mapOrAccumulate { age ->

297

validateAge(age)

298

}

299

300

when (validatedAges) {

301

is Either.Right -> println("All ages valid: ${validatedAges.value}")

302

is Either.Left -> println("Validation errors: ${validatedAges.value}")

303

}

304

```

305

306

### Padding and Alignment

307

308

```kotlin

309

import arrow.core.*

310

311

val shortList = listOf("A", "B")

312

val longList = listOf(1, 2, 3, 4)

313

314

// Pad zip handles different lengths

315

val padded = shortList.padZip(longList)

316

// Result: [(Some("A"), Some(1)), (Some("B"), Some(2)), (None, Some(3)), (None, Some(4))]

317

318

// Align with Ior

319

val aligned = shortList.align(longList)

320

// Result: [Both("A", 1), Both("B", 2), Right(3), Right(4)]

321

```

322

323

### Map Operations

324

325

```kotlin

326

import arrow.core.*

327

328

val inventory = mapOf("apples" to 10, "bananas" to 5, "oranges" to 3)

329

val prices = mapOf("apples" to 1.50, "bananas" to 0.75, "oranges" to 2.00)

330

331

// Zip maps to calculate total values

332

val values = inventory.zip(prices) { item, quantity, price ->

333

quantity * price

334

}

335

// Result: {"apples" to 15.0, "bananas" to 3.75, "oranges" to 6.0}

336

337

// Safe access with Option

338

val applePrice = prices.getOrNone("apples") // Some(1.50)

339

val grapePrice = prices.getOrNone("grapes") // None

340

```

341

342

### Sequence Processing

343

344

```kotlin

345

import arrow.core.*

346

347

// Interleave sequences

348

val evens = sequenceOf(2, 4, 6, 8)

349

val odds = sequenceOf(1, 3, 5, 7, 9)

350

351

val interleaved = evens.interleave(odds).take(8)

352

// Result: [2, 1, 4, 3, 6, 5, 8, 7]

353

354

// Filter Option sequences

355

val maybeNumbers = sequenceOf(1.some(), none(), 3.some(), none(), 5.some())

356

val numbers = maybeNumbers.filterOption()

357

// Result: [1, 3, 5]

358

```

359

360

### Either Separation

361

362

```kotlin

363

import arrow.core.*

364

365

val results = listOf(

366

"valid".right(),

367

"error1".left(),

368

"also valid".right(),

369

"error2".left()

370

)

371

372

val (errors, successes) = results.separateEither()

373

// errors: ["error1", "error2"]

374

// successes: ["valid", "also valid"]

375

```