RustyMonad


NameRustyMonad JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryRust-style Monad utils for Python
upload_time2024-09-16 15:09:33
maintainerNone
docs_urlNone
authorAkiSun
requires_python>=3.10
licenseMIT License
keywords monad functional
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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:

```bash
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

```python
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`:

```python
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`:

```python
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](LICENSE) file for details.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "RustyMonad",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "monad, functional",
    "author": "AkiSun",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/1b/fb/848a8ebc8b3e6690d1c0f64bc930a4870faf46ab5678fa7b37bc1488531f/rustymonad-1.0.0.tar.gz",
    "platform": null,
    "description": "# RustyMonad\r\n\r\nRust-Style Monad Utilities for Python\r\n\r\n## Getting Started\r\n\r\n### Introduction\r\n\r\nRustyMonad 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.\r\n\r\n### Features\r\n\r\n- **Rust-style Exception Handling**: Based on Monad's `Option` and `Result` modules, it provides a mechanism similar to Rust's exception handling\r\n- **Do-Notation Syntax Sugar**: Supports decorators to simplify monadic operations\r\n- **Match-Case Statement Support**: Supports pattern matching using match-case statements\r\n- **Complete Type Annotations**: Includes full type annotations and supports generics (use `mypy` for type checking)\r\n- **No External Dependencies**: The package does not rely on external dependencies, making it lightweight and easy to integrate\r\n\r\n### Installation\r\n\r\nRustyMonad is available on PyPI:\r\n\r\n```bash\r\npython -m pip install RustyMonad\r\n```\r\n\r\nFor optimal user experience, it is recommended to use Python 3.10 or higher to support the use of `match-case` statements.\r\n\r\n### Usage Example\r\n\r\n```python\r\nfrom rustymonad import Result, Ok, Err, DoRet, do_notation\r\n\r\n\r\ndef safe_div(x: float, y: float) -> Result[float, str]:\r\n    if y == 0:\r\n        return Err('division by zero')\r\n    return Ok(x / y)\r\n\r\n\r\ndef safe_sqrt(x: float) -> Result[float, str]:\r\n    if x < 0:\r\n        return Err('square root of a negative number')\r\n    return Ok(math.sqrt(x))\r\n\r\n\r\n@do_notation\r\ndef calc_process(a: float, b: float) -> DoRet[Result[float, str]]:\r\n    root = yield safe_sqrt(a)\r\n    quotient = yield safe_div(root, b)\r\n    return Ok(quotient)\r\n\r\n\r\nassert calc_process(9, 2) == Ok(1.5)\r\nassert calc_process(9, 0) == Err('division by zero')\r\n\r\n\r\nmatch calc_process(9, 2):\r\n    case Ok(result):\r\n        print(f'call calc_process() successful. {result = }')\r\n    case Err(error):\r\n        print(f'call calc_process() failed. {error = }')\r\n```\r\n\r\n### More Examples\r\n\r\n#### Option\r\n\r\n`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.\r\n\r\nHandling null values with `Option`:\r\n\r\n```python\r\nfrom rustymonad import Option, Some, Nothing\r\n\r\ndef safe_div(x: float, y: float) -> Option[float]:\r\n    if y == 0:\r\n        return Nothing()\r\n    return Some(x / y)\r\n\r\nother_method(safe_div(1, 0).unwrap_or(0))\r\n\r\nmatch safe_div(1, 2):\r\n    case Some(x):\r\n        print(f'result is {x}')\r\n    case Nothing():  # Also use `case _:` for the last case statement\r\n        print('cannot divide by 0')\r\n```\r\n\r\n#### Result\r\n\r\n`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)`.\r\n\r\nHandling exceptions with `Result`:\r\n\r\n```python\r\nfrom rustymonad import Result, Ok, Err\r\n\r\ndef safe_div(x: float, y: float) -> Result[float, Exception]:\r\n    try:\r\n        return Ok(x / y)\r\n    except Exception as e:\r\n        return Err(e)\r\n\r\nvalue = (\r\n    safe_div(1, 2)\r\n    .and_then(lambda x: Ok(x * x))\r\n    .or_else(lambda e: Ok(0))\r\n    .inspect(print)\r\n    .unwrap()\r\n)\r\n\r\nmatch safe_div(10, 2).and_then(lambda x: Ok(int(x))):\r\n    case Ok(v) if v % 2 == 1:\r\n        print(f'result is a odd')\r\n    case Ok(_):\r\n        print('result is a even')\r\n    case Err(e):\r\n        print(f'something wrong with {e}')\r\n```\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\r\n",
    "bugtrack_url": null,
    "license": "MIT License",
    "summary": "Rust-style Monad utils for Python",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/AkiSun/rustymonad",
        "Issues": "https://github.com/AkiSun/rustymonad/issues"
    },
    "split_keywords": [
        "monad",
        " functional"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2f093062f90b0cb39b7aa012766fda56bbae0e0b014f5b803d51dd806979358e",
                "md5": "0ec621f44b6ce48077d5e6f6bb8d2a56",
                "sha256": "2ded5f7ab84d4f0e4fa5c6d1542ce9dc82b66b845a12d2b17411784fcea9017c"
            },
            "downloads": -1,
            "filename": "RustyMonad-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0ec621f44b6ce48077d5e6f6bb8d2a56",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 7530,
            "upload_time": "2024-09-16T15:09:31",
            "upload_time_iso_8601": "2024-09-16T15:09:31.706277Z",
            "url": "https://files.pythonhosted.org/packages/2f/09/3062f90b0cb39b7aa012766fda56bbae0e0b014f5b803d51dd806979358e/RustyMonad-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1bfb848a8ebc8b3e6690d1c0f64bc930a4870faf46ab5678fa7b37bc1488531f",
                "md5": "c4b8ec38014f52ee83965586a0b05d97",
                "sha256": "f2586125aed82557751c3e7b12c491c9674226acfb7fb7db98b9de30b2abbbdb"
            },
            "downloads": -1,
            "filename": "rustymonad-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "c4b8ec38014f52ee83965586a0b05d97",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 7581,
            "upload_time": "2024-09-16T15:09:33",
            "upload_time_iso_8601": "2024-09-16T15:09:33.535922Z",
            "url": "https://files.pythonhosted.org/packages/1b/fb/848a8ebc8b3e6690d1c0f64bc930a4870faf46ab5678fa7b37bc1488531f/rustymonad-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-16 15:09:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "AkiSun",
    "github_project": "rustymonad",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "rustymonad"
}
        
Elapsed time: 1.33779s