Skip to content

Commit

Permalink
#34: add update combinator; rewrite get[State]/put[State]
Browse files Browse the repository at this point in the history
  • Loading branch information
mattfenwick committed Sep 26, 2016
1 parent 5c7fbc1 commit 147ff10
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 27 deletions.
44 changes: 25 additions & 19 deletions lib/combinators.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,35 +126,40 @@ function mapError(f, parser) {
return catchError(F.compose(error, f), parser);
}

function put(xs) {
function update(f) {
/*
m t -> Parser e s (m t) ()
(m t -> m t) -> Parser e s (m t) (m t)
*/
function f(_xs_, s) {
return good(null, xs, s);
}
return new Parser(f);
checkFunction('update', f);
return new Parser(function(xs, s) {
var ys = f(xs);
return good(ys, ys, s);
});
}

function putState(s) {
function put(xs) {
/*
s -> Parser e s (m t) ()
m t -> Parser e s (m t) (m t)
*/
function f(xs, _s_) {
return good(null, xs, s);
}
return new Parser(f);
return update(F.constF(xs));
}

function updateState(g) {
/*
(s -> s) -> Parser e s (m t) ()
*/
checkFunction('updateState', g);
function f(xs, s) {
return good(null, xs, g(s));
}
return new Parser(f);
return new Parser(function(xs, s) {
var newState = g(s);
return good(newState, xs, newState);
});
}

function putState(s) {
/*
s -> Parser e s (m t) s
*/
return updateState(F.constF(s));
}

function check(predicate, parser) {
Expand Down Expand Up @@ -377,10 +382,10 @@ function sepBy0(parser, separator) {
var zero = new Parser(function(_xs_, _s_) {return M.zero;});

// Parser e s (m t) (m t)
var get = new Parser(function(xs, s) {return good(xs, xs, s);});
var get = update(F.id);

// Parser e s (m t) s
var getState = new Parser(function(xs, s) {return good(s, xs, s);});
var getState = updateState(F.id);


function Itemizer(f) {
Expand Down Expand Up @@ -488,9 +493,10 @@ module.exports = {
'error' : error,
'catchError' : catchError,
'mapError' : mapError,
'update' : update,
'put' : put,
'putState' : putState,
'updateState': updateState,
'putState' : putState,
'check' : check,
'many0' : many0,
'many1' : many1,
Expand Down
12 changes: 11 additions & 1 deletion lib/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,22 @@ function buildSet(elems) {
return obj;
}

function constF(x) {
return function() { return x; }
}

function id(x) {
return x;
}

module.exports = {
'compose' : compose,
'getArgs' : getArgs,
'first' : first,
'second' : second,
'buildSepByValue': buildSepByValue,
'pair' : pair,
'buildSet': buildSet
'buildSet': buildSet,
'constF' : constF,
'id' : id
};
20 changes: 13 additions & 7 deletions test/combinators.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,20 +226,26 @@ testModule('combinators', function() {
deepEqual(v2, M.zero);
deepEqual(v3, good(82, '123abc', null));
});

test("Update", function() {
var v1 = C.update(function(x) {return x + 'qrs';}).parse('abc', 18);
// presents the updated "rest" as the value
deepEqual(v1, good('abcqrs', 'abcqrs', 18));
});

test("Put", function() {
var val = C.put('xyz');
deepEqual(val.parse('abc', []), good(null, 'xyz', []));
});

test("PutState", function() {
var v1 = C.putState(29).parse('abc123', 2);
deepEqual(v1, good(null, 'abc123', 29));
deepEqual(val.parse('abc', []), good('xyz', 'xyz', []));
});

test("UpdateState", function() {
var v1 = C.updateState(function(x) {return x * 4;}).parse('abc', 18);
deepEqual(v1, good(null, 'abc', 72));
deepEqual(v1, good(72, 'abc', 72));
});

test("PutState", function() {
var v1 = C.putState(29).parse('abc123', 2);
deepEqual(v1, good(29, 'abc123', 29));
});

test("Check", function() {
Expand Down
11 changes: 11 additions & 0 deletions test/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,16 @@ testModule('functions', function() {
test("buildSet", function() {
deepEqual(F.buildSet("abc"), {'a': 1, 'b': 1, 'c': 1});
});

test("constF", function() {
deepEqual(F.constF("abc")(), "abc");
deepEqual(F.constF("abc")(1, 2, 3), "abc");
deepEqual(F.constF()(1, 2, 3), undefined);
});

test("id", function() {
deepEqual(F.id(123), 123);
deepEqual(F.id(), undefined);
});

});

0 comments on commit 147ff10

Please sign in to comment.