or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-operations.mdcontainer-methods.mdcontext-operations.mdconversions.mdcore-containers.mddevelopment-tools.mdfunctional-utilities.mdindex.mditeration-utilities.mdpointfree.mdtrampolines.mdunsafe-operations.md

conversions.mddocs/

0

# Conversions

1

2

Utilities for converting between different container types and integrating with external libraries and legacy code. These functions enable seamless interoperability between monadic containers and traditional Python code.

3

4

## Capabilities

5

6

### Container Type Conversions

7

8

Functions for converting between different container types while preserving semantic meaning.

9

10

```python { .api }

11

def result_to_maybe(result_container: Result[T, E]) -> Maybe[T]:

12

"""Convert Result to Maybe, discarding error information"""

13

14

def maybe_to_result(maybe_container: Maybe[T], default_error: E = None) -> Result[T, E]:

15

"""Convert Maybe to Result, providing error for Nothing case"""

16

17

def io_to_result(io_container: IO[T]) -> IOResult[T, Exception]:

18

"""Convert IO to IOResult by catching exceptions"""

19

20

def result_to_io(result_container: Result[T, E]) -> IO[Result[T, E]]:

21

"""Lift Result into IO context"""

22

23

def future_to_future_result(future_container: Future[T]) -> FutureResult[T, Never]:

24

"""Convert Future to FutureResult (never fails)"""

25

26

def future_result_to_future(future_result: FutureResult[T, E]) -> Future[Result[T, E]]:

27

"""Convert FutureResult to Future of Result"""

28

```

29

30

Usage examples:

31

32

```python

33

from returns.converters import result_to_maybe, maybe_to_result, io_to_result

34

from returns.result import Success, Failure

35

from returns.maybe import Some, Nothing

36

from returns.io import IO

37

38

# Result to Maybe conversion

39

success_result = Success(42)

40

maybe_from_success = result_to_maybe(success_result) # Some(42)

41

42

failure_result = Failure("error occurred")

43

maybe_from_failure = result_to_maybe(failure_result) # Nothing

44

45

# Maybe to Result conversion

46

some_value = Some(42)

47

result_from_some = maybe_to_result(some_value, "no value provided") # Success(42)

48

49

nothing_value = Nothing

50

result_from_nothing = maybe_to_result(nothing_value, "no value provided") # Failure("no value provided")

51

52

# Using default error

53

result_with_default = maybe_to_result(nothing_value) # Failure(None)

54

55

# IO to Result conversion (exception handling)

56

def risky_io_operation() -> str:

57

raise ValueError("Something went wrong")

58

59

io_operation = IO(risky_io_operation)

60

io_result = io_to_result(io_operation)

61

result = io_result() # Failure(ValueError("Something went wrong"))

62

```

63

64

### Flattening Operations

65

66

Utilities for flattening nested container structures.

67

68

```python { .api }

69

def flatten(container: Container[Container[T]]) -> Container[T]:

70

"""Join two nested containers together"""

71

72

def flatten_result(nested: Result[Result[T, E], E]) -> Result[T, E]:

73

"""Flatten nested Result containers"""

74

75

def flatten_maybe(nested: Maybe[Maybe[T]]) -> Maybe[T]:

76

"""Flatten nested Maybe containers"""

77

78

def flatten_io(nested: IO[IO[T]]) -> IO[T]:

79

"""Flatten nested IO containers"""

80

81

def flatten_future(nested: Future[Future[T]]) -> Future[T]:

82

"""Flatten nested Future containers"""

83

```

84

85

Usage examples:

86

87

```python

88

from returns.converters import flatten, flatten_result, flatten_maybe

89

from returns.result import Success, Failure

90

from returns.maybe import Some, Nothing

91

92

# Generic flatten

93

nested_success = Success(Success(42))

94

flattened = flatten(nested_success) # Success(42)

95

96

nested_failure_outer = Failure("outer error")

97

flattened_outer = flatten(nested_failure_outer) # Failure("outer error")

98

99

nested_failure_inner = Success(Failure("inner error"))

100

flattened_inner = flatten(nested_failure_inner) # Failure("inner error")

101

102

# Specific flatten operations

103

nested_maybe = Some(Some("hello"))

104

flattened_maybe = flatten_maybe(nested_maybe) # Some("hello")

105

106

nested_nothing = Some(Nothing)

107

flattened_nothing = flatten_maybe(nested_nothing) # Nothing

108

109

# Practical example: nested operations

110

def validate_input(s: str) -> Result[str, str]:

111

return Success(s.strip()) if s.strip() else Failure("Empty input")

112

113

def parse_number(s: str) -> Result[Result[int, str], str]:

114

validated = validate_input(s)

115

if isinstance(validated, Success):

116

try:

117

return Success(Success(int(validated.unwrap())))

118

except ValueError:

119

return Success(Failure("Not a number"))

120

return Failure("Validation failed")

121

122

# Without flatten: Result[Result[int, str], str]

123

nested_result = parse_number("42")

124

125

# With flatten: Result[int, str]

126

flattened_result = flatten(nested_result) # Success(42)

127

```

128

129

### Legacy Code Integration

130

131

Utilities for integrating with traditional Python code that doesn't use monadic containers.

132

133

```python { .api }

134

def unsafe_perform_io(io_container: IO[T]) -> T:

135

"""Execute IO operation and return raw value (unsafe)"""

136

137

def unwrap_or_failure(container: Container[T, E], failure_value: E) -> T | E:

138

"""Unwrap container value or return failure value"""

139

140

def to_optional(container: Maybe[T]) -> T | None:

141

"""Convert Maybe to optional value (T | None)"""

142

143

def from_optional(value: T | None) -> Maybe[T]:

144

"""Convert optional value to Maybe"""

145

146

def to_exception(container: Result[T, E]) -> T:

147

"""Convert Result to value or raise exception"""

148

149

def from_exception(func: Callable[..., T]) -> Callable[..., Result[T, Exception]]:

150

"""Convert exception-throwing function to Result-returning function"""

151

```

152

153

Usage examples:

154

155

```python

156

from returns.converters import (

157

unsafe_perform_io, to_optional, from_optional,

158

to_exception, from_exception

159

)

160

from returns.io import IO

161

from returns.maybe import Some, Nothing

162

from returns.result import Success, Failure, safe

163

164

# Unsafe IO execution (for integration with legacy code)

165

def read_config() -> str:

166

return "config_data"

167

168

io_config = IO(read_config)

169

config_data = unsafe_perform_io(io_config) # "config_data"

170

171

# Maybe to optional conversion

172

some_value = Some(42)

173

optional_value = to_optional(some_value) # 42

174

175

nothing_value = Nothing

176

optional_none = to_optional(nothing_value) # None

177

178

# Optional to Maybe conversion

179

optional_data = 42

180

maybe_data = from_optional(optional_data) # Some(42)

181

182

none_data = None

183

maybe_none = from_optional(none_data) # Nothing

184

185

# Result to exception conversion (for legacy APIs)

186

success_result = Success(42)

187

value = to_exception(success_result) # 42

188

189

failure_result = Failure(ValueError("Something went wrong"))

190

# value = to_exception(failure_result) # Raises ValueError("Something went wrong")

191

192

# Exception to Result conversion

193

def legacy_function(x: int) -> int:

194

if x < 0:

195

raise ValueError("Negative value")

196

return x * 2

197

198

safe_function = from_exception(legacy_function)

199

result1 = safe_function(5) # Success(10)

200

result2 = safe_function(-5) # Failure(ValueError("Negative value"))

201

```

202

203

### Async Conversions

204

205

Utilities for converting between sync and async containers.

206

207

```python { .api }

208

def sync_to_async(container: Container[T]) -> Future[Container[T]]:

209

"""Convert sync container to async Future"""

210

211

async def async_to_sync(future_container: Future[T]) -> T:

212

"""Convert async Future to sync value (requires await)"""

213

214

def result_to_future_result(result: Result[T, E]) -> FutureResult[T, E]:

215

"""Convert Result to FutureResult"""

216

217

async def future_result_to_result(future_result: FutureResult[T, E]) -> Result[T, E]:

218

"""Convert FutureResult to Result (requires await)"""

219

220

def io_to_future(io_container: IO[T]) -> Future[T]:

221

"""Convert IO to Future"""

222

223

def future_to_io(future_container: Future[T]) -> IO[Future[T]]:

224

"""Convert Future to IO of Future"""

225

```

226

227

Usage examples:

228

229

```python

230

import asyncio

231

from returns.converters import (

232

sync_to_async, result_to_future_result,

233

future_result_to_result, io_to_future

234

)

235

from returns.result import Success, Failure

236

from returns.future import Future, FutureResult

237

from returns.io import IO

238

239

# Sync to async conversion

240

sync_result = Success(42)

241

async_result = sync_to_async(sync_result)

242

future_success = await async_result # Success(42)

243

244

# Result to FutureResult

245

result = Success(42)

246

future_result = result_to_future_result(result)

247

converted_result = await future_result # Success(42)

248

249

# FutureResult to Result

250

async def async_operation() -> Result[int, str]:

251

return Success(42)

252

253

future_result = FutureResult(async_operation())

254

sync_result = await future_result_to_result(future_result) # Success(42)

255

256

# IO to Future

257

def io_operation() -> str:

258

return "data from IO"

259

260

io_container = IO(io_operation)

261

future_container = io_to_future(io_container)

262

result = await future_container # "data from IO"

263

```

264

265

### Type Narrowing

266

267

Utilities for type narrowing and runtime type checking with containers.

268

269

```python { .api }

270

def is_success(container: Result[T, E]) -> bool:

271

"""Check if Result is Success"""

272

273

def is_failure(container: Result[T, E]) -> bool:

274

"""Check if Result is Failure"""

275

276

def is_some(container: Maybe[T]) -> bool:

277

"""Check if Maybe is Some"""

278

279

def is_nothing(container: Maybe[T]) -> bool:

280

"""Check if Maybe is Nothing"""

281

282

def success_value(container: Result[T, E]) -> T | None:

283

"""Extract value from Success, None if Failure"""

284

285

def failure_value(container: Result[T, E]) -> E | None:

286

"""Extract error from Failure, None if Success"""

287

288

def some_value(container: Maybe[T]) -> T | None:

289

"""Extract value from Some, None if Nothing"""

290

```

291

292

Usage examples:

293

294

```python

295

from returns.converters import (

296

is_success, is_failure, success_value, failure_value,

297

is_some, some_value

298

)

299

from returns.result import Success, Failure

300

from returns.maybe import Some, Nothing

301

302

# Result type checking

303

success = Success(42)

304

failure = Failure("error")

305

306

print(is_success(success)) # True

307

print(is_failure(success)) # False

308

print(is_success(failure)) # False

309

print(is_failure(failure)) # True

310

311

# Value extraction

312

success_val = success_value(success) # 42

313

success_val_from_failure = success_value(failure) # None

314

failure_val = failure_value(failure) # "error"

315

failure_val_from_success = failure_value(success) # None

316

317

# Maybe type checking

318

some = Some(42)

319

nothing = Nothing

320

321

print(is_some(some)) # True

322

print(is_nothing(some)) # False

323

print(is_some(nothing)) # False

324

print(is_nothing(nothing)) # True

325

326

# Maybe value extraction

327

some_val = some_value(some) # 42

328

some_val_from_nothing = some_value(nothing) # None

329

```

330

331

## Integration Patterns

332

333

### Gradual Migration

334

335

```python

336

from returns.converters import from_exception, to_exception

337

from returns.result import Result

338

339

# Wrap legacy function

340

def legacy_divide(a: int, b: int) -> float:

341

return a / b # May raise ZeroDivisionError

342

343

# Create safe wrapper

344

safe_divide = from_exception(legacy_divide)

345

346

# Use in functional pipeline

347

def calculate_average(numbers: list[int]) -> Result[float, Exception]:

348

if not numbers:

349

return Failure(ValueError("Empty list"))

350

351

total = sum(numbers)

352

count = len(numbers)

353

354

return safe_divide(total, count)

355

356

# Convert back for legacy code when needed

357

def legacy_api_endpoint(numbers: list[int]) -> float:

358

result = calculate_average(numbers)

359

return to_exception(result) # Raises exception if failed

360

```

361

362

### External Library Integration

363

364

```python

365

from returns.converters import from_optional, to_optional

366

from returns.maybe import Maybe

367

import json

368

from typing import Any

369

370

# Integrate with libraries that return None for missing values

371

def parse_json_field(data: str, field: str) -> Maybe[Any]:

372

try:

373

parsed = json.loads(data)

374

field_value = parsed.get(field) # Returns None if missing

375

return from_optional(field_value)

376

except json.JSONDecodeError:

377

return Nothing

378

379

# Use in functional pipeline

380

def process_config(json_str: str) -> Maybe[str]:

381

return (

382

parse_json_field(json_str, "database")

383

.bind(lambda db_config: parse_json_field(str(db_config), "url"))

384

.map(str)

385

)

386

387

# Convert back to optional for external API

388

def get_database_url(json_str: str) -> str | None:

389

result = process_config(json_str)

390

return to_optional(result)

391

```

392

393

Conversion utilities provide essential bridges between the functional programming paradigm of Returns and traditional Python code, enabling gradual adoption and seamless integration with existing codebases and libraries.