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

functional-utilities.mddocs/

0

# Functional Utilities

1

2

Core functional programming utilities for composition, transformation, and pipeline construction that enable declarative programming patterns and function composition.

3

4

## Capabilities

5

6

### Basic Functions

7

8

Essential utility functions that form the foundation of functional programming patterns.

9

10

```python { .api }

11

def identity(instance: T) -> T:

12

"""Returns its argument unchanged"""

13

14

def compose(first: Callable[[T], U], second: Callable[[U], V]) -> Callable[[T], V]:

15

"""Function composition (second after first)"""

16

17

def tap(function: Callable[[T], Any]) -> Callable[[T], T]:

18

"""Apply function for side effects, return original value"""

19

20

def untap(function: Callable[[T], Any]) -> Callable[[T], None]:

21

"""Apply function for side effects, return None"""

22

23

def raise_exception(exception: Exception) -> Callable[..., NoReturn]:

24

"""Helper to raise exceptions as a function"""

25

26

def not_(function: Callable[..., bool]) -> Callable[..., bool]:

27

"""Negate boolean function results"""

28

```

29

30

Usage examples:

31

32

```python

33

from returns.functions import identity, compose, tap, not_

34

35

# Identity function

36

value = identity(42) # 42

37

38

# Function composition

39

def add_one(x: int) -> int:

40

return x + 1

41

42

def multiply_two(x: int) -> int:

43

return x * 2

44

45

composed = compose(add_one, multiply_two)

46

result = composed(5) # (5 + 1) * 2 = 12

47

48

# Tap for side effects

49

def log_value(x: int) -> None:

50

print(f"Processing: {x}")

51

52

process_with_logging = tap(log_value)

53

result = process_with_logging(42) # Prints "Processing: 42", returns 42

54

55

# Negation

56

def is_positive(x: int) -> bool:

57

return x > 0

58

59

is_negative_or_zero = not_(is_positive)

60

result = is_negative_or_zero(-5) # True

61

```

62

63

### Pipeline Operations

64

65

Functions for creating data processing pipelines that enable point-free programming style.

66

67

```python { .api }

68

def flow(instance: T, *functions: Callable) -> Any:

69

"""Compose value with sequence of functions"""

70

71

def pipe(*functions: Callable) -> Callable:

72

"""Create function pipeline"""

73

74

def managed(use: Callable[[T], Container[U]], release: Callable[[T], Any]) -> Callable[[T], Container[U]]:

75

"""Resource management pattern"""

76

77

def is_successful(container: Container[T, E]) -> bool:

78

"""Check if container represents success"""

79

```

80

81

Usage examples:

82

83

```python

84

from returns.pipeline import flow, pipe, is_successful

85

from returns.result import Success, Failure

86

87

# Flow - immediate execution

88

result = flow(

89

10,

90

lambda x: x * 2, # 20

91

lambda x: x + 5, # 25

92

lambda x: x / 2, # 12.5

93

str # "12.5"

94

)

95

96

# Pipe - create reusable pipeline

97

process_number = pipe(

98

lambda x: x * 2,

99

lambda x: x + 5,

100

lambda x: x / 2,

101

str

102

)

103

result = process_number(10) # "12.5"

104

105

# Resource management

106

def use_file(file_path: str) -> Success[str]:

107

with open(file_path, 'r') as f:

108

return Success(f.read())

109

110

def cleanup_file(file_path: str) -> None:

111

print(f"Cleaning up {file_path}")

112

113

managed_file = managed(use_file, cleanup_file)

114

result = managed_file("data.txt")

115

116

# Success checking

117

success_result = Success(42)

118

failure_result = Failure("error")

119

120

print(is_successful(success_result)) # True

121

print(is_successful(failure_result)) # False

122

```

123

124

### Currying and Partial Application

125

126

Utilities for currying functions and partial application with proper type safety.

127

128

```python { .api }

129

def partial(func: Callable, *args, **kwargs) -> Callable:

130

"""Typed partial application wrapper"""

131

132

def curry(function: Callable) -> Callable:

133

"""Decorator for currying functions"""

134

```

135

136

Usage examples:

137

138

```python

139

from returns.curry import partial, curry

140

141

# Partial application

142

def add_three_numbers(a: int, b: int, c: int) -> int:

143

return a + b + c

144

145

add_10_and = partial(add_three_numbers, 10)

146

add_10_and_5 = partial(add_10_and, 5)

147

result = add_10_and_5(3) # 18

148

149

# Currying

150

@curry

151

def multiply_three(a: int, b: int, c: int) -> int:

152

return a * b * c

153

154

# Can be called in multiple ways

155

result1 = multiply_three(2)(3)(4) # 24

156

result2 = multiply_three(2, 3)(4) # 24

157

result3 = multiply_three(2)(3, 4) # 24

158

result4 = multiply_three(2, 3, 4) # 24

159

160

# Partial application with curried function

161

double = multiply_three(2)

162

quadruple = double(2)

163

result = quadruple(5) # 20

164

```

165

166

### Container Conversion

167

168

Utilities for converting between different container types and flattening nested structures.

169

170

```python { .api }

171

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

172

"""Joins two nested containers together"""

173

174

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

175

"""Converts Result to Maybe"""

176

177

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

178

"""Converts Maybe to Result"""

179

```

180

181

Usage examples:

182

183

```python

184

from returns.converters import flatten, result_to_maybe, maybe_to_result

185

from returns.result import Success, Failure

186

from returns.maybe import Some, Nothing

187

188

# Flatten nested containers

189

nested_success = Success(Success(42))

190

flattened = flatten(nested_success) # Success(42)

191

192

nested_maybe = Some(Some("hello"))

193

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

194

195

# Result to Maybe conversion

196

success_result = Success(42)

197

maybe_from_success = result_to_maybe(success_result) # Some(42)

198

199

failure_result = Failure("error")

200

maybe_from_failure = result_to_maybe(failure_result) # Nothing

201

202

# Maybe to Result conversion

203

some_value = Some(42)

204

result_from_some = maybe_to_result(some_value, "default error") # Success(42)

205

206

nothing_value = Nothing

207

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

208

```

209

210

### Method Utilities

211

212

Standalone utility methods for conditional creation and container manipulation.

213

214

```python { .api }

215

def cond(condition: bool, success_value: T, failure_value: E) -> Result[T, E]:

216

"""Conditional container creation"""

217

218

def partition(containers: Iterable[Result[T, E]]) -> tuple[list[T], list[E]]:

219

"""Partition containers by success/failure"""

220

221

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

222

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

223

```

224

225

Usage examples:

226

227

```python

228

from returns.methods import cond, partition, unwrap_or_failure

229

from returns.result import Success, Failure

230

231

# Conditional creation

232

def validate_age(age: int) -> Result[int, str]:

233

return cond(age >= 18, age, "Must be 18 or older")

234

235

result1 = validate_age(25) # Success(25)

236

result2 = validate_age(15) # Failure("Must be 18 or older")

237

238

# Partition results

239

results = [

240

Success(1),

241

Failure("error1"),

242

Success(2),

243

Failure("error2"),

244

Success(3)

245

]

246

247

successes, failures = partition(results)

248

# successes: [1, 2, 3]

249

# failures: ["error1", "error2"]

250

251

# Unwrap with fallback

252

success_container = Success(42)

253

value1 = unwrap_or_failure(success_container, "fallback") # 42

254

255

failure_container = Failure("error")

256

value2 = unwrap_or_failure(failure_container, "fallback") # "fallback"

257

```

258

259

## Composition Patterns

260

261

### Pipeline Style

262

263

```python

264

from returns.pipeline import flow

265

from returns.functions import compose

266

267

# Sequential processing

268

data = flow(

269

"hello world",

270

str.upper, # "HELLO WORLD"

271

lambda s: s.split(), # ["HELLO", "WORLD"]

272

len, # 2

273

lambda n: n * 10 # 20

274

)

275

276

# Reusable composed function

277

process_text = compose(

278

lambda s: s.split(),

279

len

280

)

281

```

282

283

### Point-free Style

284

285

```python

286

from returns.curry import curry

287

from returns.functions import compose

288

289

@curry

290

def add(a: int, b: int) -> int:

291

return a + b

292

293

@curry

294

def multiply(a: int, b: int) -> int:

295

return a * b

296

297

# Point-free composition

298

add_five = add(5)

299

double = multiply(2)

300

process = compose(add_five, double)

301

302

result = process(10) # (10 + 5) * 2 = 30

303

```

304

305

These functional utilities provide the building blocks for creating clean, composable, and reusable code following functional programming principles while maintaining full type safety.