A lightweight Python implementation of a Maybe monad
Project description
talvez
A lightweight Python implementation of a Maybe monad (Just / Nothing) inspired by the R package "maybe".
Features
- Just(value) and Nothing singleton.
- Decorators:
@maybe(...)turns a function into one returningMaybe.@perhaps(default=..., ...)returns raw value or a default.
- Functor map:
fmap - Monadic bind:
bind - Pipeline helpers:
chain,compose_maybe - Conversions:
from_optional,sequence - Predicates and combinators:
not_null,not_nan,not_infinite,not_undefined,not_empty,and_,or_
Installation
pip install talvez
# or (development)
pip install -e .
Quick Start
from talvez import maybe, just
@maybe()
def parse_int(s: str) -> int:
return int(s)
@maybe(ensure=lambda x: x != 0)
def reciprocal(n: int) -> float:
return 1 / n
result = (
parse_int("25")
.bind(reciprocal)
.fmap(lambda x: x * 100)
)
print(result) # Just(4.0)
print(result.get_or(-1)) # 4.0
bad = (
parse_int("not a number")
.bind(reciprocal)
.fmap(lambda x: x * 100)
)
print(bad) # Nothing
Functor and Monad
fmap(fn)applies a pure transformation:Maybe a->Maybe bbind(fn)sequences a computation returning aMaybe:a -> Maybe b
from talvez import just
res = just(5).fmap(lambda x: x + 2).bind(lambda x: just(x * 10))
print(res) # Just(70)
Predicates
from talvez import not_null, not_infinite, and_
p = and_(not_null, not_infinite)
print(p(10)) # True
print(p(float('inf'))) # False
Sequencing Pipelines
Use chain for immediate execution:
from talvez import chain, just, maybe
@maybe()
def step1(x: int): return x + 1
@maybe()
def step2(x: int): return x * 2
@maybe(ensure=lambda v: v < 50)
def step3(x: int): return x + 10
result = chain(just(5), step1, step2, step3)
print(result) # Just(22)
Use compose_maybe to build a reusable pipeline:
from talvez import compose_maybe, just
pipeline = compose_maybe(step1, step2, step3)
print(pipeline(just(5))) # Just(22)
Rule of thumb:
- Use
chainfor ad-hoc immediate sequences. - Use
compose_maybefor reusable or shareable pipelines.
perhaps Decorator
from talvez import perhaps
@perhaps(default=0)
def parse_int_default(s: str) -> int:
return int(s)
print(parse_int_default("42")) # 42
print(parse_int_default("x")) # 0
Interop
from talvez import from_optional
maybe_val = from_optional(None) # Nothing
maybe_val2 = from_optional("hello") # Just("hello")
sequence
from talvez import just, nothing, sequence
values = [just(1), just(2), just(3)]
print(sequence(iter(values))) # Just([1, 2, 3])
mixed = [just(1), nothing(), just(3)]
print(sequence(iter(mixed))) # Nothing
Warning Handling
Functions wrapped with @maybe or @perhaps treat Python warnings as failures unless allow_warning=True.
import warnings
from talvez import maybe
@maybe(allow_warning=False)
def noisy():
warnings.warn("careful")
return 10
print(noisy()) # Nothing
Testing
pytest
License
GPL-3.0-or-later
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file talvez-0.0.9.tar.gz.
File metadata
- Download URL: talvez-0.0.9.tar.gz
- Upload date:
- Size: 24.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4657cdb913975ab74ac60c7f530c32895f8784543ac1a4f858a9f66e27ded7d0
|
|
| MD5 |
739d444611a4dd58e2180cd9ec32e96f
|
|
| BLAKE2b-256 |
dbbcc6d2fdf51baef0c8d3b09262f3e1e532b133e6ac1853a737e56e70f50a7b
|
File details
Details for the file talvez-0.0.9-py3-none-any.whl.
File metadata
- Download URL: talvez-0.0.9-py3-none-any.whl
- Upload date:
- Size: 24.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fae175c83351e532067542f0544aadf3581d4766a53054428b9cb63ba4f35a1f
|
|
| MD5 |
ca2704d773bb1c8835827a5a11e51a6c
|
|
| BLAKE2b-256 |
752258aa3eb432b9a222be1f4812aa2248649f07a00477c1e7995829cb1759d6
|