GitHub - santinic/pampy.js: Pampy.js: Pattern Matching for JavaScript
source link: https://github.com/santinic/pampy.js
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
README.md
Pampy.js: Pattern Matching for JavaScript
Pampy.js is pretty small (250 lines), reasonably fast, and often makes your code more readable, and easier to reason about. There is also a Python version of Pampy.
You can write many patterns
Patterns are evaluated in the order they appear.
You can write Fibonacci
The operator _ means "any other case I didn't think of". If you already use _
, you can require ANY
, which is exactly the same.
let {match, _} = require("pampy"); function fib(n) { return match(n, 1, 1, 2, 1, _, (x) => fib(x - 1) + fib(x - 2) ); }
You can write a Lisp calculator in 5 lines
let {match, REST, _} = require("pampy"); function lisp(exp) { return match(exp, Function, (x) => x, [Function, REST], (f, rest) => f.apply(null, rest.map(lisp)), Array, (l) => l.map(lisp), _, (x) => x ); let plus = (a, b) => a + b; let minus = (a, b) => a - b; let reduce = (f, l) => l.reduce(f); lisp([plus, 1, 2]); // => 3 lisp([plus, 1, [minus, 4, 2]]); // => 3 lisp([reduce, plus, [1, 2, 3]]); // => 6
You can match so many things!
let {match, _} = require("pampy"); match(x, 3, "this matches the number 3", Number, "matches any javascript number", [String, Number], (a, b) => "a typed list [a, b] that you can use in a function", [1, 2, _], "any list of 3 elements that begins with [1, 2]", {x: _}, "any dict with a key 'x' and any value associated", _, "anything else" )
You can match TAIL
let {match, _, TAIL} = require("pampy"); x = [1, 2, 3]; match(x, [1, TAIL], (t) => t); // => [2, 3] match(x, [_, TAIL], (h, t) => [h, t]); // => [1, [2, 3])
You can nest lists and tuples
let {match, _, TAIL} = require("pampy"); x = [1, [2, 3], 4]; match(x, [1, [_, 3], _], (a, b) => [1, [a, 3], b]); // => [1, [2, 3], 4]
You can nest dicts. And you can use _ as key!
pet = { type: 'dog', details: { age: 3 } }; match(pet, {details: {age: _}}, (age) => age); // => 3 match(pet, {_: {age: _}}, (a, b) => [a, b]); // => ['details', 3]
Admittedly using _
as key is a bit of a trick, but it works for most situations.
All the things you can match
Pattern Example
What it means
Matched Example
Arguments Passed to function
NOT Matched Example
"hello"
only the string "hello"
matches
"hello"
nothing
any other value
Number
Any javascript number
2.35
2.35
any other value
String
Any javascript string
"hello"
"hello"
any other value
Array
Any array object
[1, 2]
[1, 2]
any other value
_
Any object
that value
ANY
The same as _
that value
[1, 2, _]
A list that starts with 1, 2 and ends with any value
[1, 2, 3]
3
[1, 2, 3, 4]
[1, 2, TAIL]
A list that start with 1, 2 and ends with any sequence
[1, 2, 3, 4]
[3, 4]
[1, 7, 7, 7]
{type:'dog', age: _ }
Any dict with type: "dog"
and with an age
{type:"dog", age: 3}
3
{type:"cat", age:2}
{type:'dog', age: Number }
Any dict with type: "dog"
and with an numeric age
{type:"dog", age: 3}
3
{type:"dog", age:2.3}
null
only null
null
nothing
any other value
undefined
only undefined
undefined
nothing
any other value
How to install
npm install pampy
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK