An experimental implementation of a monad with adding Python-specific and practical enhancements.
result, err = (
Maybe(5)
.bind(sqrt)
.bind(pow, 4)
.resolve_as(int)
)
print("Result:", result or err) # 25Python error handling can be difficult to manage, especially when chaining multiple operations that may fail. The Maybe monad provides a way to encapsulate values that may or may not produce an exception, allowing for cleaner and more readable code. It can also be used to enforce type constraints at runtime.
This implementation also includes custom error error handling that captures the context of where an error occurred, making debugging easier.
The Maybe class is initialized with a value:
Maybe(value)
You can then chain operations using the bind method, which takes a function and optional arguments. If any operation raises an exception, the chain is short-circuited, and the error is stored:
Maybe(value).bind(func, *args, **kwargs)Finally, you can use the resolve_as method to attempt to extract the value, enforcing a type constraint if desired. Tuple unpacking can be used to make this more convenient:
result, error = Maybe(value).bind(func).resolve_as(expected_type)Like Go's error handling, you can check if an error occurred by inspecting the second element of the returned tuple:
result, error = Maybe(value).bind(func).resolve_as(expected_type)
if error:
print("An error occurred:", error)
# Handle the error here
# Continue with result if no errorexamples.py contains example usage.
This package is not on PyPI, but you can install it directly from the repository using pip or uv:
# pip
pip install git+https://github.com/MatthewCane/monadic-python-demo
# uv
uv add git+https://github.com/MatthewCane/monadic-python-demo