Skip to main content

Pattern Matching with XObject.

Project description

Xpattern: Pattern Matching with XObject.

GitHub Tests PyPI version

xpattern is inspired by hask, pipetools, pampy, and with xpattern your code will be more readable and graceful!

Let's play now

Each pattern matchline evaluated in the order they appear.

from xpattern import caseof
from xpattern import m


~(caseof(v)
    | m(pattern_1) >> action_1
    | m(pattern_2) >> action_2
)

caseof is lazy, so you need to add ~ operator to run it!

Write a Fibonacci

The operator _ means "match everything"

from xpattern import _
from xpattern import caseof
from xpattern import m


def fibonacci(n):
    return ~(caseof(n)
        | m(1) >> 1
        | m(2) >> 1
        | m(_) >> (lambda x: fibonacci(x - 1) + fibonacci(x - 2))
    )

Write a Lisp calculator

from functools import reduce

from xpattern import _
from xpattern import REST
from xpattern import caseof
from xpattern import m


def lisp(exp):
    return ~(caseof(exp)
        | m(int)            >> (lambda x: x)
        | m(callable)       >> (lambda x: x)
        | m(callable, REST) >> (lambda f, rest: f(*map(lisp, rest)))
        | m(tuple)          >> (lambda t: list(map(lisp, t)))
    )

plus = lambda a, b: a + b
minus = lambda a, b: a - b
lisp((plus, 1, 2))                  # => 3
lisp((plus, 1 (minus, 4, 2)))       # => 3
lisp((reduce, plus, (range, 10)))   # => 45

You can match so many things!

~(caseof(x)
    | m(3)         >> "this matches the number 3"
    | m(int)       >> "matches any integer"
    | m(str, int)  >> (lambda a, b: "a tuple (a, b) you can use in a function")
    | m(1, 2, _)   >> "any list of 3 elements that begins with [1, 2]"
    | m({"x", _})  >> "any dict with a key 'x' and any value associated"
    | m(_)         >> "anything else"
)

Match [HEAD, TAIL]

from xpattern import _
from xpattern import HEAD
from xpattern import TAIL
from xpattern import caseof
from xpattern import m


x = [1, 2, 3]

~(caseof(x)
    | m(1, TAIL) >> (lambda t: t)             # => [2, 3]
)

~(caseof(x)
    | m(HEAD, TAIL) >> (lambda h, t: (h, t))  # => [1, [2, 3]]
)

More pattern cases

Your can visit repo pampy get more pattern cases, xpattern is Syntactic Sugar of pampy

Why name Xpattern, what's X mean?

X means XObject !!!

XObject is a Syntactic Sugar of lambda function

from xpattern import X
from xpattern import caseof
from xpattern import m


~(caseof(1)
    | m(1) >> X + 1       # => 2
)

~(caseof("apple")
    | m(str) >> X.upper()  # => "APPLE"
)

~(caseof([1, 2, 3])
    | m(1, 2, 3) >> X[2]   # => 3
)

~(caseof([1, 2, 3])
    | m(1, 2, 3) >> X + [4, 5, 6]   # => [1, 2, 3, 4, 5, 6]
)

~(caseof(9)
    | m(int) >> X + X ** (X << 2) % 2 / 3 - X  # => 0.333333333
)

~(caseof(1)
    | m(int) >> X._in_([1, 2, 3])   # => True
)

~(caseof(lambda x, y: x + y)
    | m(callable) >> X(1, 2)   # => 3
)
Operation Syntax
Addition X + 1
Call X(a, b, c)
Concatenation X + [1, 2, 3]
Containment Test X._in_( [1, 2, 3] )
Contains X._contains_(1)
Division X / 2 or X // 2
Bitwise And X & 2
Bitwise Exclusive Or X ^ 2
Bitwise Inversion ~X
Bitwise Or X | 2
Exponentiation X ** 2
Identity X._is_(2)
Indexing X[k]
Left Shift X << 2
Modulo X % 2
Multiplication X * 2
Matrix Multiplication X @ matrix
Negation (Arithmetic) -X
Negation (Logical) X._not()
Positive +X
Right Shift X >> 2
Subtraction X - 2
Ordering X < 2 or X <= 2 or X > 2 or X >= 2
Equality X == 2
Difference X != 2

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

xpattern-0.2.0.tar.gz (6.9 kB view hashes)

Uploaded Source

Built Distribution

xpattern-0.2.0-py3-none-any.whl (6.2 kB view hashes)

Uploaded Python 3

Supported by

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