Skip to content

jaredly/js_deep_ppx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

[@js.deep] for immutably updating javascript objects in Reason/OCaml

Motivation: Reason has this nice syntax for constructing javascript objects {"some": thing}, and a nice way to represent the types type t = {. "some": int}, and so it can be quite convenient when working with external javascript libraries to just keep everything in the original data format ... that is, until you want to update something. Mutative updates require creating externals for every field, and trying to update things immutably is an exercise in frustration.

That's where js.deep comes in! This ppx allows you to retain type safety, while making immutable updates to deeply nested javascript objects almost painless.

Usage:

js.deep transforms code that looks like some_value["attrname"].replace(newvalue) into code that does the equivalent of the javascript {...some_value, attrname: newvalue}, and some_value["attrname"].map(somefn) with {...some_value, attrname: somefn(some_value.attrname)}.

// Some nested data
let one = {"one": {"two": {"three": 4}}};

// Updating a field -- this replaces the value at "three" with 5
let two = [%js.deep one["one"]["two"]["three"].replace(5)];
/* Fails type check (arg needs to be an int)
let two = [%js.deep one["one"]["two"]["three"].replace(5.0)];
*/

assert(two == {"one": {"two": {"three": 5}}});

// Updating a field with a map function, increasing the value by 10
let three = [%js.deep one["one"]["two"]["three"].map(n => n + 10)];
/* Fails type check (transform function expects a float, gets an int)
let two = [%js.deep one["one"]["two"]["three"].map(n => n +. 1.0)];
*/

assert(three == {"one": {"two": {"three": 14}}});

/* Fails type check (accessing paths that don't exist)
let two = [%js.deep one["one"]["two"]["five"].replace(5)];
let two = [%js.deep one["one"]["three"]["five"].replace(5)];
*/

let other = {"one": {"two": {"three": {"four": 4, "five": 5}}}};

// map + replace!
let other_new = [%js.deep other["one"]["two"]["three"].map(
  // update two fields
  three => three["four"].replace(10)["five"].replace(50)
)];
assert(other_new == {"one": {"two": {"three": {"four": 10, "five": 50}}}})

Installation

npm i js_deep_ppx

bsconfig.json

"ppx-flags": ["js_deep_ppx/ppx"]

About

[@js.deep] for immutably updating nested javascript objects in Reason/OCaml

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published