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

pointfree.mddocs/

0

# Point-free Operations

1

2

Point-free style functions that enable composition without explicitly naming intermediate values, supporting functional programming idioms and container manipulation through higher-order functions.

3

4

## Capabilities

5

6

### Core Point-free Functions

7

8

Essential point-free operations that work with all container types for monadic composition.

9

10

```python { .api }

11

def bind(func: Callable[[T], Container[U]]) -> Callable[[Container[T]], Container[U]]:

12

"""Monadic bind operation (flatMap)"""

13

14

def map_(func: Callable[[T], U]) -> Callable[[Container[T]], Container[U]]:

15

"""Transform successful/present values"""

16

17

def apply(wrapped_func: Container[Callable[[T], U]]) -> Callable[[Container[T]], Container[U]]:

18

"""Apply wrapped function to wrapped value"""

19

20

def alt(func: Callable[[E], F]) -> Callable[[Container[T, E]], Container[T, F]]:

21

"""Transform error values"""

22

23

def lash(func: Callable[[E], Container[T, F]]) -> Callable[[Container[T, E]], Container[T, F]]:

24

"""Handle error cases with recovery"""

25

26

def swap() -> Callable[[Container[T, E]], Container[E, T]]:

27

"""Swap success and failure values"""

28

```

29

30

Usage examples:

31

32

```python

33

from returns.pointfree import bind, map_, alt, lash

34

from returns.result import Success, Failure, Result

35

from returns.pipeline import flow

36

37

# Point-free bind

38

def double(x: int) -> Result[int, str]:

39

return Success(x * 2)

40

41

def validate_positive(x: int) -> Result[int, str]:

42

return Success(x) if x > 0 else Failure("Must be positive")

43

44

# Traditional style

45

result = Success(5).bind(double).bind(validate_positive)

46

47

# Point-free style

48

pipeline = flow(

49

Success(5),

50

bind(double),

51

bind(validate_positive)

52

)

53

54

# Point-free map

55

def add_one(x: int) -> int:

56

return x + 1

57

58

transform = map_(add_one)

59

result = transform(Success(42)) # Success(43)

60

61

# Point-free alt for error transformation

62

def format_error(error: str) -> str:

63

return f"Error: {error}"

64

65

handle_error = alt(format_error)

66

result = handle_error(Failure("invalid input")) # Failure("Error: invalid input")

67

```

68

69

### Specialized Bind Operations

70

71

Type-specific bind operations for different container combinations.

72

73

```python { .api }

74

def bind_result(func: Callable[[T], Result[U, E]]) -> Callable[[Container[T]], Container[U, E]]:

75

"""Bind operation specialized for Result"""

76

77

def bind_io(func: Callable[[T], IO[U]]) -> Callable[[Container[T]], Container[U]]:

78

"""Bind operation specialized for IO"""

79

80

def bind_future(func: Callable[[T], Future[U]]) -> Callable[[Container[T]], Container[U]]:

81

"""Bind operation specialized for Future"""

82

83

def bind_async(func: Callable[[T], Awaitable[U]]) -> Callable[[Container[T]], Awaitable[Container[U]]]:

84

"""Bind operation for async functions"""

85

86

def bind_context(func: Callable[[T], RequiresContext[U, Deps]]) -> Callable[[RequiresContext[T, Deps]], RequiresContext[U, Deps]]:

87

"""Bind operation for context-dependent computations"""

88

```

89

90

Usage examples:

91

92

```python

93

from returns.pointfree import bind_result, bind_io, bind_context

94

from returns.result import Success, safe

95

from returns.io import IO

96

from returns.context import RequiresContext

97

98

# Specialized Result bind

99

@safe

100

def parse_int(s: str) -> int:

101

return int(s)

102

103

@safe

104

def divide_by_two(x: int) -> float:

105

return x / 2

106

107

process_string = flow(

108

Success("42"),

109

bind_result(parse_int),

110

bind_result(divide_by_two)

111

) # Success(21.0)

112

113

# IO bind

114

def read_file(path: str) -> IO[str]:

115

return IO(lambda: open(path).read())

116

117

def process_content(content: str) -> IO[int]:

118

return IO(lambda: len(content))

119

120

process_file = flow(

121

IO(lambda: "data.txt"),

122

bind_io(read_file),

123

bind_io(process_content)

124

)

125

126

# Context bind

127

def get_config() -> RequiresContext[dict, dict]:

128

return RequiresContext(lambda env: env["config"])

129

130

def get_database_url(config: dict) -> RequiresContext[str, dict]:

131

return RequiresContext(lambda env: config["db_url"])

132

133

get_db_url = flow(

134

RequiresContext.ask(),

135

bind_context(get_config),

136

bind_context(get_database_url)

137

)

138

```

139

140

### Context Manipulation

141

142

Functions for working with context-dependent computations.

143

144

```python { .api }

145

def modify_env(func: Callable[[Deps], NewDeps]) -> Callable[[RequiresContext[T, Deps]], RequiresContext[T, NewDeps]]:

146

"""Modify the environment/context"""

147

148

def local(func: Callable[[Deps], NewDeps]) -> Callable[[RequiresContext[T, NewDeps]], RequiresContext[T, Deps]]:

149

"""Run computation with modified local context"""

150

```

151

152

Usage example:

153

154

```python

155

from returns.pointfree import modify_env

156

from returns.context import RequiresContext

157

158

class Config:

159

def __init__(self, debug: bool, db_url: str):

160

self.debug = debug

161

self.db_url = db_url

162

163

def enable_debug(config: Config) -> Config:

164

return Config(True, config.db_url)

165

166

def get_db_connection() -> RequiresContext[str, Config]:

167

return RequiresContext(lambda cfg: f"Connected to {cfg.db_url} (debug={cfg.debug})")

168

169

# Modify context before operation

170

debug_connection = flow(

171

get_db_connection(),

172

modify_env(enable_debug)

173

)

174

175

config = Config(False, "postgresql://localhost")

176

result = debug_connection(config) # "Connected to postgresql://localhost (debug=True)"

177

```

178

179

### Composition Utilities

180

181

Advanced composition functions for complex pipelines.

182

183

```python { .api }

184

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

185

"""Unify container types for composition"""

186

187

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

188

"""Compose functions that return Results"""

189

190

def rescue(func: Callable[[E], Container[T, F]]) -> Callable[[Container[T, E]], Container[T, F]]:

191

"""Recover from errors with alternative computation"""

192

```

193

194

Usage examples:

195

196

```python

197

from returns.pointfree import compose_result, rescue

198

from returns.result import Success, Failure, safe

199

200

# Compose Result-returning functions

201

@safe

202

def parse_int(s: str) -> int:

203

return int(s)

204

205

@safe

206

def square(x: int) -> int:

207

return x * x

208

209

@safe

210

def to_string(x: int) -> str:

211

return str(x)

212

213

process_pipeline = compose_result(parse_int, square, to_string)

214

result = process_pipeline("5") # Success("25")

215

216

# Error recovery

217

def handle_parse_error(error: Exception) -> Result[int, str]:

218

return Success(0) if "invalid literal" in str(error) else Failure("Unexpected error")

219

220

safe_parse = flow(

221

safe(int)("invalid"),

222

rescue(handle_parse_error)

223

) # Success(0)

224

```

225

226

### Container-specific Operations

227

228

Specialized operations for specific container types.

229

230

```python { .api }

231

# Maybe-specific

232

def or_else(default: Maybe[T]) -> Callable[[Maybe[T]], Maybe[T]]:

233

"""Provide alternative Maybe if Nothing"""

234

235

def or_else_call(func: Callable[[], Maybe[T]]) -> Callable[[Maybe[T]], Maybe[T]]:

236

"""Provide alternative Maybe from function if Nothing"""

237

238

# Result-specific

239

def value_or(default: T) -> Callable[[Result[T, E]], T]:

240

"""Extract value or return default"""

241

242

def unwrap_or(default: T) -> Callable[[Container[T]], T]:

243

"""Unwrap container value or return default"""

244

245

# IO-specific

246

def unsafe_perform_io() -> Callable[[IO[T]], T]:

247

"""Execute IO operation (unsafe)"""

248

```

249

250

Usage examples:

251

252

```python

253

from returns.pointfree import or_else, value_or, unwrap_or

254

from returns.maybe import Some, Nothing

255

from returns.result import Success, Failure

256

257

# Maybe alternatives

258

maybe_value = Nothing

259

default_some = Some("default")

260

261

result = or_else(default_some)(maybe_value) # Some("default")

262

263

# Result value extraction

264

success_result = Success(42)

265

failure_result = Failure("error")

266

267

get_value = value_or(0)

268

value1 = get_value(success_result) # 42

269

value2 = get_value(failure_result) # 0

270

271

# Universal unwrap

272

unwrap_safe = unwrap_or("fallback")

273

value3 = unwrap_safe(Success("hello")) # "hello"

274

value4 = unwrap_safe(Failure("error")) # "fallback"

275

```

276

277

## Point-free Composition Patterns

278

279

### Pipeline Construction

280

281

```python

282

from returns.pointfree import bind, map_, alt

283

from returns.pipeline import flow

284

from returns.result import Success, safe

285

286

# Build processing pipeline

287

@safe

288

def parse_float(s: str) -> float:

289

return float(s)

290

291

def format_currency(amount: float) -> str:

292

return f"${amount:.2f}"

293

294

def handle_error(error: Exception) -> str:

295

return "Invalid amount"

296

297

process_amount = flow(

298

bind(parse_float),

299

map_(format_currency),

300

alt(lambda _: "Invalid amount")

301

)

302

303

result = process_amount(Success("123.456")) # Success("$123.46")

304

```

305

306

### Function Composition

307

308

```python

309

from returns.pointfree import bind, map_

310

from returns.curry import curry

311

312

@curry

313

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

314

return a + b

315

316

@curry

317

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

318

return a * b

319

320

# Point-free arithmetic pipeline

321

add_five = add(5)

322

double = multiply(2)

323

324

arithmetic = flow(

325

map_(add_five),

326

map_(double)

327

)

328

329

result = arithmetic(Success(10)) # Success(30)

330

```

331

332

### Error Handling Pipeline

333

334

```python

335

from returns.pointfree import lash, alt, rescue

336

from returns.result import Failure, Success

337

338

def retry_once(error: str) -> Result[int, str]:

339

return Success(42) if "retry" in error else Failure("Failed permanently")

340

341

def log_error(error: str) -> str:

342

print(f"Error occurred: {error}")

343

return error

344

345

error_pipeline = flow(

346

lash(retry_once), # Try to recover

347

alt(log_error) # Log if still failing

348

)

349

350

result = error_pipeline(Failure("retry please")) # Success(42)

351

```

352

353

Point-free operations enable clean, composable functional programming by removing the need to explicitly name intermediate values, leading to more readable and maintainable code pipelines.