or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

collections.mderror-handling.mdfunctional-utilities.mdinclusive-or.mdindex.mdoptional-values.mdraise-dsl.md

optional-values.mddocs/

0

# Optional Values with Option

1

2

Safe handling of optional values without null pointer exceptions. Option provides a type-safe alternative to nullable types with comprehensive functional operations and guaranteed null safety.

3

4

## Capabilities

5

6

### Option Construction

7

8

Create Option instances representing presence or absence of values.

9

10

```kotlin { .api }

11

/**

12

* Option containing a value

13

*/

14

data class Some<out A>(val value: A) : Option<A>

15

16

/**

17

* Option representing absence of value

18

*/

19

object None : Option<Nothing>

20

21

/**

22

* Create Option from potentially null value

23

*/

24

fun <A> Option.Companion.fromNullable(value: A?): Option<A>

25

```

26

27

### Option Extension Functions

28

29

Convenience functions for creating Option instances.

30

31

```kotlin { .api }

32

/**

33

* Wrap any value in Some

34

*/

35

fun <A> A.some(): Some<A>

36

37

/**

38

* Create None instance with specific type

39

*/

40

fun <A> none(): Option<A>

41

```

42

43

**Usage Examples:**

44

45

```kotlin

46

// Direct construction

47

val present: Option<String> = Some("hello")

48

val absent: Option<String> = None

49

50

// From nullable values

51

val maybeUser = Option.fromNullable(findUserById(123))

52

53

// Using extension functions

54

val greeting = "Hello".some()

55

val empty: Option<String> = none()

56

```

57

58

### Option Type Guards

59

60

Check the state of Option instances with type-safe guards.

61

62

```kotlin { .api }

63

/**

64

* Check if Option contains a value

65

* @return true if Some, false if None

66

*/

67

fun <A> Option<A>.isSome(): Boolean

68

69

/**

70

* Check if Option is empty

71

* @return true if None, false if Some

72

*/

73

fun <A> Option<A>.isNone(): Boolean

74

```

75

76

### Option Pattern Matching

77

78

Safely extract values or perform operations based on Option state.

79

80

```kotlin { .api }

81

/**

82

* Pattern match on Option, providing handlers for both cases

83

*/

84

fun <A, B> Option<A>.fold(

85

ifEmpty: () -> B,

86

ifSome: (A) -> B

87

): B

88

89

/**

90

* Extract the value or compute a default

91

*/

92

fun <A> Option<A>.getOrElse(default: () -> A): A

93

94

/**

95

* Extract the value or return null

96

*/

97

fun <A> Option<A>.getOrNull(): A?

98

99

/**

100

* Extract the value or return null (alias for getOrNull)

101

*/

102

fun <A> Option<A>.orNull(): A?

103

```

104

105

**Usage Examples:**

106

107

```kotlin

108

val maybeAge: Option<Int> = Some(25)

109

110

// Pattern matching

111

val description = maybeAge.fold(

112

ifEmpty = { "Age not provided" },

113

ifSome = { age -> "Age is $age" }

114

)

115

116

// Extract with default

117

val age = maybeAge.getOrElse { 0 }

118

119

// Extract as nullable

120

val nullableAge: Int? = maybeAge.getOrNull()

121

```

122

123

### Option Transformations

124

125

Transform Option values while preserving the container structure.

126

127

```kotlin { .api }

128

/**

129

* Transform the contained value if present

130

*/

131

fun <A, B> Option<A>.map(f: (A) -> B): Option<B>

132

133

/**

134

* Monadic bind - chain operations that may return None

135

*/

136

fun <A, B> Option<A>.flatMap(f: (A) -> Option<B>): Option<B>

137

138

/**

139

* Keep value only if it satisfies the predicate

140

*/

141

fun <A> Option<A>.filter(predicate: (A) -> Boolean): Option<A>

142

143

/**

144

* Keep value only if it does NOT satisfy the predicate

145

*/

146

fun <A> Option<A>.filterNot(predicate: (A) -> Boolean): Option<A>

147

```

148

149

**Usage Examples:**

150

151

```kotlin

152

val maybeNumber: Option<String> = Some("42")

153

154

// Transform value

155

val doubled = maybeNumber

156

.map { it.toInt() }

157

.map { it * 2 }

158

// Result: Some(84)

159

160

// Chain operations

161

val result = maybeNumber

162

.flatMap { str ->

163

if (str.all { it.isDigit() }) Some(str.toInt()) else None

164

}

165

.filter { it > 10 }

166

// Result: Some(42)

167

```

168

169

### Option Filtering

170

171

Filter Option values based on predicates.

172

173

```kotlin { .api }

174

/**

175

* Keep value only if it satisfies the predicate

176

*/

177

fun <A> Option<A>.filter(predicate: (A) -> Boolean): Option<A>

178

179

/**

180

* Keep value only if it does NOT satisfy the predicate

181

*/

182

fun <A> Option<A>.filterNot(predicate: (A) -> Boolean): Option<A>

183

```

184

185

### Option Conversions

186

187

Convert Option to other types and collections.

188

189

```kotlin { .api }

190

/**

191

* Convert Option to List (empty list for None, single-item list for Some)

192

*/

193

fun <A> Option<A>.toList(): List<A>

194

195

/**

196

* Convert Option to Either, providing error for None case

197

*/

198

fun <A, E> Option<A>.toEither(ifEmpty: () -> E): Either<E, A>

199

```

200

201

**Usage Examples:**

202

203

```kotlin

204

val maybeValue: Option<String> = Some("hello")

205

206

// Convert to List

207

val list = maybeValue.toList() // ["hello"]

208

209

// Convert to Either

210

val either = maybeValue.toEither { "Value was not provided" }

211

// Result: Either.Right("hello")

212

213

val emptyOption: Option<String> = None

214

val emptyList = emptyOption.toList() // []

215

val leftEither = emptyOption.toEither { "Missing value" }

216

// Result: Either.Left("Missing value")

217

```

218

219

### Option Combination

220

221

Combine multiple Option values.

222

223

```kotlin { .api }

224

/**

225

* Combine two Options using a transformation function

226

* Returns Some only if both Options are Some

227

*/

228

fun <A, B, C> Option<A>.zip(other: Option<B>, transform: (A, B) -> C): Option<C>

229

230

/**

231

* Combine two Options into a Pair

232

* Returns Some only if both Options are Some

233

*/

234

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

235

```

236

237

**Usage Examples:**

238

239

```kotlin

240

val firstName: Option<String> = Some("John")

241

val lastName: Option<String> = Some("Doe")

242

243

// Combine with transformation

244

val fullName = firstName.zip(lastName) { first, last -> "$first $last" }

245

// Result: Some("John Doe")

246

247

// Combine into Pair

248

val namePair = firstName.zip(lastName)

249

// Result: Some(Pair("John", "Doe"))

250

```

251

252

### Option Utilities

253

254

Additional utility functions for working with Option.

255

256

```kotlin { .api }

257

/**

258

* Return this Option if it's Some, otherwise return the alternative

259

*/

260

fun <A> Option<A>.orElse(alternative: () -> Option<A>): Option<A>

261

262

/**

263

* Apply a side effect if Option is Some, return original Option

264

*/

265

fun <A> Option<A>.onSome(action: (A) -> Unit): Option<A>

266

267

/**

268

* Apply a side effect if Option is None, return original Option

269

*/

270

fun <A> Option<A>.onNone(action: () -> Unit): Option<A>

271

```

272

273

**Usage Examples:**

274

275

```kotlin

276

val primary: Option<String> = None

277

val backup: Option<String> = Some("backup value")

278

279

// Use alternative if primary is None

280

val result = primary.orElse { backup }

281

// Result: Some("backup value")

282

283

// Side effects

284

val logged = Some("important data")

285

.onSome { value -> println("Processing: $value") }

286

.onNone { println("No data to process") }

287

```

288

289

## Collection Extensions

290

291

Extensions for working with collections of Option values.

292

293

```kotlin { .api }

294

/**

295

* Sequence a collection of Options into an Option of collection

296

* Returns Some(list) only if all Options are Some

297

*/

298

fun <A> Iterable<Option<A>>.sequence(): Option<List<A>>

299

300

/**

301

* Transform collection to Options and sequence the results

302

*/

303

fun <A, B> Iterable<A>.traverse(f: (A) -> Option<B>): Option<List<B>>

304

305

/**

306

* Keep only Some values from collection of Options

307

*/

308

fun <A> Iterable<Option<A>>.catOptions(): List<A>

309

```

310

311

**Usage Examples:**

312

313

```kotlin

314

val options = listOf(Some(1), Some(2), Some(3))

315

val sequenced = options.sequence() // Some([1, 2, 3])

316

317

val mixed = listOf(Some(1), None, Some(3))

318

val mixedSequenced = mixed.sequence() // None

319

320

val values = mixed.catOptions() // [1, 3]

321

```