Skip to content

Instantly share code, notes, and snippets.

@carstenlenz
Created June 24, 2013 08:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carstenlenz/5848588 to your computer and use it in GitHub Desktop.
Save carstenlenz/5848588 to your computer and use it in GitHub Desktop.
JavaScript optional result values
var optional = (function() {
var noneInternal = function() {};
noneInternal.prototype.isNone = function() { return true; };
noneInternal.prototype.isSome = function() { return false; };
noneInternal.prototype.bind = function(fun) { return none(); };
var none = function() {
return new noneInternal(); // make fiddling less probable
};
someIsNone = function() { return false; };
someIsSome = function() { return true; };
someBind = function(fun) {
var ret = fun(this());
return create(ret);
};
var some = function(value) {
var result = function() {
return value;
};
result.isNone = someIsNone;
result.isSome = someIsSome;
result.bind = someBind;
return result;
}
var create = function(value) {
if (value != null) {
return some(value);
}
return none();
};
return {
create: create,
none: none,
some: some
};
})();
module("optional");
test("null should yield none", function() {
var o = optional.create(null);
ok(o.isNone());
ok(!o.isSome());
o = optional.none();
ok(o.isNone());
ok(!o.isSome());
});
test("null should throw if called", function() {
throws(
function() {
var o = optional.none();
o();
});
});
test("null bind should always return none", function() {
var o = optional.none();
var o1 = o.bind(function(value) {
return optional.create("not called");
});
ok(o1.isNone());
});
test("value should yield some", function() {
var o = optional.create("hello");
ok(o.isSome());
ok(!o.isNone());
});
test("invoking some should return value", function() {
var o = optional.some("hamsdi");
equal(o(), "hamsdi");
});
test("binding some should be invoked", function() {
var o = optional.some("hamsdi");
o.bind(function(value) {
equal(value, "hamsdi");
});
});
test("non null result of binding should be itself be some", function() {
var o1 = optional.some("hamsdi");
var o2 = o1.bind(function(value) {
equal(value, "hamsdi");
return "bamsdi";
});
ok(o2.isSome());
});
test("null result of binding should be itself be none", function() {
var o1 = optional.some("hamsdi");
var o2 = o1.bind(function(value) {
equal(value, "hamsdi");
return null;
});
ok(o2.isNone());
});
test("binding cascade", function() {
var my = optional.create("hamsdi");
var r = my.bind(function(value) {
return value + " bamsdi";
}).bind(function(value) {
return "Hello " + value;
}).bind(function(value) {
return value + "!";
});
equal(r(), "Hello hamsdi bamsdi!");
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment