Functional programming patterns for Python - pragmatic, type-safe, and developer-friendly.
Monads & Functional Types
Maybe[T]- Handle optional values safelyResult<T, E>- Explicit error handlingEither<L, R>- Two-value alternativesValidation<T, E>- Accumulate validation errors- And more:
Try,IO,Reader,Writer,State,Task, etc.
Functional Collections
MappableList[T]- List with functional operationsImmutableDict[K, V]- Safe immutable dictionariesLazySequence[T]- Lazy evaluation sequencesBidirectionalMap[K, V]- Two-way lookups
Function Utilities
curry(f)- Incremental argument applicationcompose(f, g)- Function compositionpipe(value, f, g)- Left-to-right pipelinespartial(f, ...)- Fix function arguments
OOP-First Design
- Protocol-based (like
collections.abc) - Generic types with full type hints
- Method chaining and fluent APIs
- Modern Python patterns (dataclasses, protocols, etc.)
from better_py import Maybe, Result, pipe
# Maybe: Safe optional handling
user = Maybe.from_value(get_user(id))
name = user.map(lambda u: u.name).unwrap_or_else(lambda: "Guest")
# Result: Explicit error handling
def divide(a: int, b: int) -> Result[float, str]:
if b == 0:
return Result.error("Division by zero")
return Result.ok(a / b)
result = divide(10, 2)
if result.is_ok():
print(f"Result: {result.unwrap()}")
else:
print(f"Error: {result.unwrap_error()}")
# Pipe: Data pipelines
result = pipe(
data,
validate,
transform,
save
)# Install from PyPI
pip install better-py
# Or with uv (recommended)
uv pip install better-pyRequirements: Python 3.11+
Not academic functional programming - practical patterns that make software development easier.
Full type hints with mypy strict mode. Catch errors before runtime.
Everything is an object. Operations are functional. Works naturally with Python.
Clear error messages, helpful APIs, extensive documentation.
# REST API error handling
from better_py import Result
async def get_user(id: int) -> Result[User, Error]:
user = await db.fetch_user(id)
if not user:
return Result.error(Error("User not found"))
return Result.ok(user)
# Data validation
from better_py import Validation
email_validated = Validation.validate(email, EmailValidator())
password_validated = Validation.validate(password, PasswordValidator())
user_validation = email_validated.and_then(password_validated)
if user_validation.is_valid():
create_user(email, password)
# Data processing pipeline
from better_py import pipe
result = pipe(
raw_data,
clean,
validate,
transform,
load_to_db
)Current Version: 0.1.0 (Alpha)
What's Working:
- โ Documentation framework
- โ CI/CD pipeline
- โ Type system design
In Development:
- ๐ Core protocols (Mappable, Reducible, etc.)
- ๐ Monad implementations
- ๐ Functional collections
- ๐ Function utilities
Planned:
- ๐ More monads (Writer, State, etc.)
- ๐ Performance benchmarks
- ๐ Integration examples (FastAPI, SQLAlchemy, etc.)
See Issues for detailed roadmap.
Contributions are welcome! Please see CONTRIBUTING.md for details.
Quick start:
# Clone repository
git clone https://github.com/nesalia-inc/better-py.git
cd better-py
# Install with uv
uv venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
uv sync --all-extras
# Run tests
uv run pytest
# Run checks
uv run ruff check .
uv run mypy better_pyMIT License - see LICENSE for details.
Inspired by:
- GitHub: nesalia-inc/better-py
- Issues: GitHub Issues
Made with โค๏ธ by nesalia-inc