A library which provides simple functional pattern matching.
Project description
pymatched⇒
What is pymatched?
pymatched is a library which provides functional pattern matching.
Installation
pip install pymatched
Syntax
result = match(<'func'>) >> Mapping[Hashable, Any]
Match order
- exact match
- oneof match
- placeholder match (if target is immutable iterable)
- type match with guard (Contravariant match)
- type match (Invariant match)
- type match (Contravariant match)
- handling default if exists
Usage
Note: How to match mutable value?
as you know, mutable things cannot be key of dict so we can not match easly.
this is the example of list.
Case A: use type guards
x = match([1, 2, 3]) >> {
list : "list",
oneof([1], [1, 2], [1, 2, 3]) : "[1] | [1, 2] | [1, 2, 3]",
(list, lambda x: x == [1, 2, 3]): "(list, f(list) -> bool)",
# [1, 2, 3]: "[1, 2, 3]", --> list is unhashable so not working
}
Case B: use nested match
x = match([1, 2, 3]) >> {
list: match(...) >> {
(list, lambda v: v == [1, _, 3]): "pattern is (1, * ,3)",
... : "default"
}
}
Value match
from pymatched import match
match(1) >> {
1: "It's 1",
5: "It's 5",
}
Handling default case
use elipsis ...
or typing.Any
if nothing catched but default handler not defined, RuntimeError will be raised.
from typing import Any
from pymatched import match
match(None) >> {
...: "default",
# Any: "also default",
}
Type match
from pymatched import match
match(42) >> {
int: "int caught",
...: lambda v: f"{type(v)} caught"
}
Type match with guard
If tuple's first element is type and second element is lambda, this case will be considered as type match with guard.
from pymatched import match
match(42) >> {
(int, lambda: v: v == 42): "42 caught",
int : "int except 42",
}
type match with guard can use typing.Any
.
from typing import Any
from pymatched import match
match(42) >> {
(Any, lambda: v: v in (42, "42")): "42 caught",
int : "int except 42",
}
Exception match in type match
pymatched.do
wraps executing function. when wrapped function raises error, do
catch it and return it as normal return.
from pymatched import match, do
def fx(v):
raise Exception("Ooops!")
match(do(fx, None)) >> {
Exception: "exception caught",
... : lambda v: f"{v} caught",
}
Oneof match
from pymatched import oneof, match
fx = lambda x: x
match(fx(5)) >> {
oneof(1, 2, 3): "one of 1, 2, 3",
oneof(4, 5, 6): "one of 4, 5, 6",
}
Placeholder match
from pymatched import oneof, match
match((1, 2, 3, 4)) >> { # change (1, 2, 3, 4) into (100, 2, 3, 4) or (1, 9, 3, 9)
(1, _, 3, _): "pattern (1, *, 3, *)",
(_, 2, _, 4): "pattern (*, 2, *, 4)",
}
Nested match
If match with pymatchied._
(PlaceholderTyoe) or ...
(Ellipsis), this match will be considered as nested match.
from pymatched import match, _
match(5) >> {
int: match(_) >> {
5: "It's 5",
...: "default"
},
}
Mixed match
cases could be mixed, but resolved by designated match order.
from pymatched import oneof, match
v = (1, 2, 3)
x = match(v) >> {
tuple : "Tuple caught",
(tuple, lambda v: v[-1] == 3) : "last item of tuple is 3",
(1, _, 3) : "pattern is (1, *, 3)".
oneof((1,), (1, 2), (1, 2, 3)): "one of (1,) | (1, 2) | (1, 2, 3)",
(1, 2, 3) : "(1, 2, 3)"
}
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
Hashes for pymatched-0.2.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4793328686476c3aa014eafb160ab1eef9f4a22385a859ab452db67b23c5a6c0 |
|
MD5 | 1cf6786c510d0bb2042432c4fe2d9cf2 |
|
BLAKE2b-256 | 51d89f0dec6e2563534c8cd571122818d6c4859fd31e023586bdbe0492e8814b |