JavaScript Pattern Matching

Introduction

Let's first create a new object, and bind _ to Pattern_Matching::variable for a little more sanity

      var m = new Pattern_Matching ();
      var _ = m.variable;
    

Doing some pattern matching is really easy, and looks pretty much like pattern matching in other languages.

A pattern can be anything : Object, Array, Number, String, Boolean, you name it. In turn, any variable foo in a pattern is denoted by Pattern_Matching::variable("foo") (here written _("foo")

This means that matching {foo:"bar", bar:"baz"} with {foo:_("quux")} will imply that you can access quux in your callback function, and it will have a value of "bar".

An few examples might be clearer...

Factorial

      function fact (n) {
        return m.match(n, 
        [
          [    0  , function ( ) { return 1                    }],
          [ _("n"), function (a) { return (a.n * fact(a.n -1)) }]
        ]);
      }
    

Factorial = 24

Deconstructing complex structures

      function go_deep(ob) {
        return m.match(ob,
        [
          [{foo:{bar:{baz:'foo'}}, baz:_('b')}, function (a) { return a.b  }],
          [_('_')                             , function ( ) { return null }]
        ]);
      }
    

Matched content :

Emulating Variant Types

      var hd = function (l) {
        return m.match(l,
        [
          [{Nil:_("_")}           , function ( ) { throw "empty list" }],
          [{Cons:[_("t"), _("_")]}, function (a) { return a.t         }]
        ]);
      }
      
      var tl = function (l) {
        return m.match(l,
        [
          [{Nil:_("_")}           , function ( ) { throw "empty list" }],
          [{Cons:[_("t"), _("q")]}, function (a) { return a.q         }]
        ]);
      }

      var iter = function (f, l) {
        return m.match(l,
        [
          [{Nil:_("_")}           , function ( ) {                     }],
          [{Cons:[_("t"), _("q")]}, function (a) { f(a.t); iter(f,a.q) }]
        ]);
      }

      var l = {Cons:[42, {Cons:[2, {Nil:null}]}]}
    

Push :