Skip to main content

Rust-style Monad utils for Python

Project description

RustyMonad

Rust-Style Monad Utilities for Python

Getting Started

Introduction

RustyMonad is a Python package designed to incorporate a Rust-style exception handling mechanisms into Python programming. This approach not only simplifies code and also enhances its readability and maintainability.

Features

  • Rust-style Exception Handling: Based on Monad's Option and Result modules, it provides a mechanism similar to Rust's exception handling
  • Do-Notation Syntax Sugar: Supports decorators to simplify monadic operations
  • Match-Case Statement Support: Supports pattern matching using match-case statements
  • Complete Type Annotations: Includes full type annotations and supports generics (use mypy for type checking)
  • No External Dependencies: The package does not rely on external dependencies, making it lightweight and easy to integrate

Installation

RustyMonad is available on PyPI:

python -m pip install RustyMonad

For optimal user experience, it is recommended to use Python 3.10 or higher to support the use of match-case statements.

Usage Example

from rustymonad import Result, Ok, Err, DoRet, do_notation


def safe_div(x: float, y: float) -> Result[float, str]:
    if y == 0:
        return Err('division by zero')
    return Ok(x / y)


def safe_sqrt(x: float) -> Result[float, str]:
    if x < 0:
        return Err('square root of a negative number')
    return Ok(math.sqrt(x))


@do_notation
def calc_process(a: float, b: float) -> DoRet[Result[float, str]]:
    root = yield safe_sqrt(a)
    quotient = yield safe_div(root, b)
    return Ok(quotient)


assert calc_process(9, 2) == Ok(1.5)
assert calc_process(9, 0) == Err('division by zero')


match calc_process(9, 2):
    case Ok(result):
        print(f'call calc_process() successful. {result = }')
    case Err(error):
        print(f'call calc_process() failed. {error = }')

More Examples

Option

Option[T] is used to represent an optional(nullable) value, typically used for type declarations. Option[T] can either contain a value Some(T) or be empty Nothing(). This can replace the Optional type from the typing module. Nothing behaves similarly to None but supports branch selection or null value handling through interfaces to avoid using numerous if statements for null checks.

Handling null values with Option:

from rustymonad import Option, Some, Nothing

def safe_div(x: float, y: float) -> Option[float]:
    if y == 0:
        return Nothing()
    return Some(x / y)

other_method(safe_div(1, 0).unwrap_or(0))

match safe_div(1, 2):
    case Some(x):
        print(f'result is {x}')
    case Nothing():  # Also use `case _:` for the last case statement
        print('cannot divide by 0')

Result

Result[T, E] is commonly used to represent the result of an operation or any exceptions generated during the operation. It is generally used for type declarations. Result[T, E] can either contain a success value Ok(T) or an error Err(E).

Handling exceptions with Result:

from rustymonad import Result, Ok, Err

def safe_div(x: float, y: float) -> Result[float, Exception]:
    try:
        return Ok(x / y)
    except Exception as e:
        return Err(e)

value = (
    safe_div(1, 2)
    .and_then(lambda x: Ok(x * x))
    .or_else(lambda e: Ok(0))
    .inspect(print)
    .unwrap()
)

match safe_div(10, 2).and_then(lambda x: Ok(int(x))):
    case Ok(v) if v % 2 == 1:
        print(f'result is a odd')
    case Ok(_):
        print('result is a even')
    case Err(e):
        print(f'something wrong with {e}')

License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rustymonad-1.0.0.tar.gz (7.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

RustyMonad-1.0.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

Details for the file rustymonad-1.0.0.tar.gz.

File metadata

  • Download URL: rustymonad-1.0.0.tar.gz
  • Upload date:
  • Size: 7.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.4

File hashes

Hashes for rustymonad-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f2586125aed82557751c3e7b12c491c9674226acfb7fb7db98b9de30b2abbbdb
MD5 c4b8ec38014f52ee83965586a0b05d97
BLAKE2b-256 1bfb848a8ebc8b3e6690d1c0f64bc930a4870faf46ab5678fa7b37bc1488531f

See more details on using hashes here.

File details

Details for the file RustyMonad-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: RustyMonad-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 7.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.4

File hashes

Hashes for RustyMonad-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2ded5f7ab84d4f0e4fa5c6d1542ce9dc82b66b845a12d2b17411784fcea9017c
MD5 0ec621f44b6ce48077d5e6f6bb8d2a56
BLAKE2b-256 2f093062f90b0cb39b7aa012766fda56bbae0e0b014f5b803d51dd806979358e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page