Matching module¶
The Match module¶
This module implements a technique for pattern matching.
High-level functions¶
-
kingston.match.
matches
(values: Sequence[T_co], patterns: Sequence[T_co], matchfn: Callable = <function match>) → Union[Sequence[T_co], Type[kingston.match.Miss]][source]¶ Tries to match
values
frompatterns
.Parameters: - values – A sequence of values to match.
- patterns – A sequence of patterns that may match
values
.
Returns: The pattern that was matched or
Miss
.Return type: Union[Sequence, Type[Miss]]
High-level classes¶
-
class
kingston.match.
Matcher
[source]¶ Common base for all matcher classes.
Since
Matcher
is alsoGeneric
, you use it to subtype concrete instances of matchers you implement.
-
class
kingston.match.
TypeMatcher
[source]¶ Concrete implementation of a type matcher instance.
If you want to type a type matcher, use standard technique when using
Generic
types:>>> from kingston.match import Matcher, TypeMatcher >>> my_int_matcher:Matcher[int, int] = TypeMatcher({ ... int: lambda x: x+1, ... str: lambda x: 'str'}) >>> my_int_matcher(10) 11 >>> my_int_matcher(20) 21 >>> my_int_matcher('foo') # ok at runtime but fails mypy 'str' >>>
You can also subclass type matchers and use a decorator to declare cases as methods:
>>> from kingston.match import Matcher, TypeMatcher, case >>> from numbers import Number >>> class NumberDescriber(TypeMatcher): ... @case ... def describe_one_int(self, one:int) -> str: ... return "One integer" ... ... @case ... def describe_two_ints(self, one:int, two:int) -> str: ... return "Two integers" ... ... @case ... def describe_one_float(self, one:float) -> str: ... return "One float" >>> my_num_matcher:Matcher[Number, str] = NumberDescriber() >>> my_num_matcher(1) 'One integer' >>> my_num_matcher(1, 2) 'Two integers' >>> my_num_matcher(1.0) 'One float' >>>
-
class
kingston.match.
ValueMatcher
[source]¶ Concrete implementation of a value matching instance.
If you want to type a type matcher, use standard technique when using
Generic
types:>>> from kingston.match import ValueMatcher, Miss >>> my_val_matcher:Matcher[int, str] = ValueMatcher({ ... 1: lambda x: 'one!', ... 2: lambda x: 'two!', ... Miss: lambda x: 'many!'}) >>> my_val_matcher(1) 'one!' >>> my_val_matcher(2) 'two!' >>> my_val_matcher(3) 'many!' >>> my_val_matcher('x') # ok at runtime but fails mypy (& missleading..) 'many!' >>>
You can also declare cases as methods in a custom
ValueMatcher
subclass.Use the function
value_case()
to declare value cases. Note: imported as a shorthand:>>> from kingston.match import Matcher, ValueMatcher >>> from kingston.match import value_case as case >>> class SimplestEval(ValueMatcher): ... @case(Any, '+', Any) ... def _add(self, a, op, b) -> int: ... return a + b ... ... @case(Any, '-', Any) ... def _sub(self, a, op, b) -> int: ... return a - b >>> simpl_eval = SimplestEval() >>> simpl_eval(1, '+', 2) 3 >>> simpl_eval(10, '-', 5) 5
Exceptions and symbols¶
-
exception
kingston.match.
Conflict
[source]¶ Exception raised if a pattern to be matched already have been applied to a Matcher instance.
Low-level functions¶
-
kingston.match.
match
(cand: Any, pattern: Any) → bool[source]¶ ”Primitive” function that checks an individual value against another. Checking against
Any
works as a wildcard and will always result inTrue
.
-
kingston.match.
move
(left: Sequence[T_co], pattern: Sequence[T_co], matchfn: Callable = <function match>)[source]¶ One step of the pattern matching process. The
move()
function will take to sequences (left
,pattern
) that represents the current state of matching and produce a tuple representing the next (left
,pattern
) pair of the pattern matching.Parameters: - left – Values that haven’t been matched yet.
- pattern – Pattern values to match subsequently.
- matchfn – Function that should compare a pair of values.
Returns: A pair representing the next step in the matching process.
Return type: Tuple[Sequence,Sequence]