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
```