Can I pattern match on JS objects?

1.4k views Asked by At

Given a function that accesses a property of a JavaScript object—

let useFoo x => Js.log x##foo;

useFoo {"foo": 10};

—is there a way to rewrite it to pattern match for the property?

I'd hoped that something like this would work, but the syntax is invalid:

let useFoo {"foo"} => Js.log foo;
1

There are 1 answers

1
Bluddy On BEST ANSWER

There's no way to do this, and the reason for this is that Javascript objects - which are little more than mappings of keys to values - are handled using Reason's (ie. OCaml's) object-oriented system. In Reason/OCaml, you cannot pattern match over functions ie. if I have a record containing a lambda, I cannot pattern match over the result of applying that lambda:

type t = {foo: int => int};

let bar {foo} => foo 5;

Notice that I can pattern match and get the foo lambda out of the record, but I can't apply foo inside the pattern match -- I have to apply it to the argument '5' after I extracted it.

Here's the problem with objects: the only interface to objects in Reason is via their public methods. Methods are like lambdas, except that their first argument is always self, which is the object itself. So every time we access x##foo, we're really dispatching the foo method, feeding it x as an argument, and getting the result back. Just as we can't pattern match in Reason over function application, we can't pattern match over objects either, since objects are just collections of functions that get applied automatically.