Package: xpattern
Xpattern: Pattern Matching with XObject.xpatternis inspired byhask,pipetools,pampy, and withxpatternyour code will be more readable and graceful!Let's play nowEach pattern matchline evaluated in the order they appear.fromxpatternimportcaseoffromxpatternimportm~(caseof(v)|m(pattern_1)>>action_1|m(pattern_2)>>action_2)caseofis lazy, so you need to add~operator to run it!mis a matcher, if you don't likecircular bracketsstyle, you can alse usesquare bracketsstylefromxpatternimportcaseoffromxpatternimportm~(caseof(v)|m[pattern_1]>>action_1|m[pattern_2]>>action_2)Write a FibonacciThe operator_means "match everything"fromxpatternimport_fromxpatternimportcaseoffromxpatternimportmdeffibonacci(n):return~(caseof(n)|m(1)>>1|m(2)>>1|_>>(lambdax:fibonacci(x-1)+fibonacci(x-2)))Write a Lisp calculatorfromfunctoolsimportreducefromxpatternimport_fromxpatternimportRESTfromxpatternimportcaseoffromxpatternimportmdeflisp(exp):return~(caseof(exp)|m(int)>>(lambdax:x)|m(callable)>>(lambdax:x)|m(callable,REST)>>(lambdaf,rest:f(*map(lisp,rest)))|m(tuple)>>(lambdat:list(map(lisp,t))))plus=lambdaa,b:a+bminus=lambdaa,b:a-blisp((plus,1,2))# => 3lisp((plus,1(minus,4,2)))# => 3lisp((reduce,plus,(range,10)))# => 45You can match so many things!~(caseof(x)|m(3)>>"this matches the number 3"|m(int)>>"matches any integer"|m(str,int)>>(lambdaa,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"|_>>"anything else")Match dataclassfromdataclassesimportdataclassfromxpatternimport_fromxpatternimportcaseoffromxpatternimportm@dataclassclassPoint:x:inty:int@dataclassclassPoint2:x:inty:int@dataclassclassLine:p1:Pointp2:Point@dataclassclassRect:l1:Linel2:Line~(caseof(Rect(Point(1,2),Point(3,4)))|m(Rect(Point(_,str),Point(_,4)))>>"first"|m(Rect(Point(_,int),Point2(_,4)))>>"second"|m(Rect(Point(_,int),Point(_,4)))>>(lambdax,y,z:(x,y,z)))# => (1, 2, 3)Match [HEAD, TAIL]fromxpatternimport_fromxpatternimportHEADfromxpatternimportTAILfromxpatternimportcaseoffromxpatternimportmx=[1,2,3]~(caseof(x)|m(1,TAIL)>>(lambdat:t)# => [2, 3])~(caseof(x)|m(HEAD,TAIL)>>(lambdah,t:(h,t))# => [1, [2, 3]])Chain matchfromxpatternimport_fromxpatternimportcaseoffromxpatternimportmpet={"type":"dog","details":{"age":3}}~(caseof(pet)|m({_:{"age":_}})>>~(caseof(X)|m(int,int)>>(lambdax,y:x+y)|m(str,int)>>(lambdax,y:y)))# => 3With Bitwise Operatorsfromxpatternimport_fromxpatternimportcaseoffromxpatternimportm~(caseof(1)|(m[2]|m[1])>>1|_>>"nothing")# => 1~(caseof(11)|(m[lambdax:x>1]&m[lambdax:x<10])>>"1 < x < 10"|(m[lambdax:x>1]&m[lambdax:x<15])>>"1 < x < 15")# => "1 < x < 15"~(caseof(6)|~m[lambdax:x>5]>>"x <=5"|~m[lambdax:x>10]>>"x <= 10")# => "x <= 10"More pattern casesYour can visit repopampyget more pattern cases,xpatternisSyntactic SugarofpampyWhy nameXpattern, what'sXmean?XmeansXObject!!!XObjectis aSyntactic SugaroflambdafunctionfromxpatternimportXfromxpatternimportcaseoffromxpatternimportm~(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(lambdax,y:x+y)|m(callable)>>X(1,2)# => 3)OperationSyntaxAdditionX + 1CallX(a, b, c)ConcatenationX + [1, 2, 3]Containment TestX._in_( [1, 2, 3] )ContainsX._contains_(1)DivisionX / 2orX // 2Bitwise AndX & 2Bitwise Exclusive OrX ^ 2Bitwise Inversion~XBitwise OrX | 2ExponentiationX ** 2IdentityX._is_(2)IndexingX[k]Left ShiftX << 2ModuloX % 2MultiplicationX * 2Matrix MultiplicationX @ matrixNegation (Arithmetic)-XNegation (Logical)X._not()Positive+XRight ShiftX >> 2SubtractionX - 2OrderingX < 2orX <= 2orX > 2orX >= 2EqualityX == 2DifferenceX != 2match pattern with XObjectfromxpatternimportXfromxpatternimportcaseoffromxpatternimportm~(caseof((1,2,3))|m(X[2]==3)>>X[2]+4# => 7)# same as~(caseof((1,2,3))|m(lambdax:x[2]==3)>>(lambdax:x[2]+4)# => 7)xfunctionXObjectonly can represent as function likeX(1, 2), but can not be as args in functionfunc(X, X + 2)Now you can try to usexfunctionrealizing it!fromxpatternimportXfromxpatternimport_fromxpatternimportcaseoffromxpatternimportmfromxpatternimportxfunction@xfunctiondefadd(a,b):returna+b# in actions~(caseof(1)|m(int)>>add(X,X)# => 2)# recursion xfunction~(caseof(2)|m(int)>>add(add(X+1,4),b=add(X*9,7))# => 32)@xfunctiondefgreater_than_4(x):returnx>4# in patterns~(caseof(1)|m(greater_than_4(X+5))>>"greater than 4"|_>>"equal or lesser than 4")# => "greater than 4"~(caseof(1)|m(greater_than_4(X))>>"greater than 4"|_>>"equal or lesser than 4")# => "equal or lesser than 4"