Hacker News new | ask | show | jobs
by mpfundstein 2985 days ago
Shameless plug but here is my pattern machter [1] :D

Example:

    // simple factorial
    const factorial = n => match(n)
        .when(0, 1)
        .otherwise(n => n * factorial(n - 1));

    // walking a tree
    class Tree {
        constructor(left, right) {
                this.left = left;
                this.right = right;
        }
    }

    class Node {
        constructor(value) {
                this.value = value;
        }
    }

    const T = (l, r) => new Tree(l, r);
    const N = v => new Node(v);

    const walkT = t => match(t)
        .when(Node, v => console.log(v.value))
        .when(Tree, t => { walkT(t.left); walkT(t.right)})
        .otherwise(_ => 'error');

    const mapT = (f, t) => match(t)
        .when(Node, v => N(f(v.value)))
        .when(Tree, t => T(mapT(f, t.left), mapT(f, t.right)))
        .otherwise(_ => { throw new Error('error') });
Works also on deeply nested objects.

[1] https://github.com/MarkusPfundstein/pmatch-js

1 comments

Method-based syntax for pattern matching is easier to read and grok (IMO), but it lacks the dynamic capabilities of data-oriented syntax (in Kasai, patterns can be built/manipulated at runtime). It's interesting to compare the two approaches.
If you mean by method-based pattern matching that you evaluate a function for each 'case'. My lib can do that do:

    const match = require('pmatch-js')
    const _ = require('lodash')

    const fizzbuzz = x => match(x)
      .when(a => a % 3 == 0 && a % 5 == 0, 'fizzbuzz')
      .when(a => a % 5 == 0, 'buzz')
      .when(a => a % 3 == 0, 'fizz')
      .otherwise(a => a)

    console.log(
      _.range(1, 101).map(fizzbuzz).join(' ')
    )
But maybe you mean something totally different :-)

EDIT: Ah I think I know what you mean. Your lib takes an array of tuples to define the patterns. Sorry for the confusion.

Wow, importing the whole lodash to use just one function? There’s es6 way of getting an array with a range of numbers:

    [...Array(100).keys()].map(v=>v+1)
A little bit longer but no dependencies.
Although this method is pretty, I see 4 loops in this small line. a better way would be to only import the range method from lodash like so :

    import _range from "lodash/range";
Pretty cool trick mate. Didn’t know