Created
June 18, 2014 10:34
-
-
Save plainOldCode/c3116adc6b950461deee to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var _ = require('underscore'); | |
function splat(fun) { | |
return function(array) { | |
return fun.apply(null, array); | |
}; | |
} | |
function unsplat(fun) { | |
return function() { | |
return fun.call(null, _.toArray(arguments)); | |
}; | |
} | |
function fail(thing) { | |
throw new Error(thing); | |
} | |
function warn(thing) { | |
console.log(["WARNING:", thing].join(' ')); | |
} | |
function note(thing) { | |
console.log(["NOTE:", thing].join(' ')); | |
} | |
function naiveNth(a, index) { | |
return a[index]; | |
} | |
function isIndexed(data) { | |
return _.isArray(data) || _.isString(data); | |
} | |
function nth(a, index) { | |
if (!_.isNumber(index)) fail("Expected a number as the index"); | |
if (!isIndexed(a)) fail("Not supported on non-indexed type"); | |
if ((index < 0) || (index > a.length - 1)) | |
fail("Index value is out of bounds"); | |
return a[index]; | |
} | |
function second(a) { | |
return nth(a, 1); | |
} | |
function existy(x) { return x != null }; | |
function truthy(x) { return (x !== false) && existy(x) }; | |
function doWhen(cond, action) { | |
if(truthy(cond)) | |
return action(); | |
else | |
return undefined; | |
} | |
function executeIfHasField(target, name) { | |
return doWhen(existy(target[name]), function() { | |
var result = _.result(target, name); | |
console.log(['The result is', result].join(' ')); | |
return result; | |
}); | |
} | |
function validator(message, fun) { | |
var f = function(/* args */) { | |
return fun.apply(fun, arguments); | |
}; | |
f['message'] = message; | |
return f; | |
} | |
function cat() { | |
var head = _.first(arguments); | |
if (existy(head)) | |
return head.concat.apply(head, _.rest(arguments)); | |
else | |
return []; | |
} | |
function construct(head, tail) { | |
return cat([head], _.toArray(tail)); | |
} | |
function always(VALUE) { | |
return function() { | |
return VALUE; | |
}; | |
}; | |
function invoker (NAME, METHOD) { | |
return function(target /* args ... */) { | |
if (!existy(target)) fail("Must provide a target"); | |
var targetMethod = target[NAME]; | |
var args = _.rest(arguments); | |
return doWhen((existy(targetMethod) && METHOD === targetMethod), function() { | |
return targetMethod.apply(target, args); | |
}); | |
}; | |
}; | |
var rev = invoker('reverse', Array.prototype.reverse); | |
function isEven(n) { return (n%2) === 0 }; | |
function complement(PRED) { | |
return function() { | |
return !PRED.apply(null, _.toArray(arguments)); | |
}; | |
} | |
var isOdd = complement(isEven); | |
var zero = validator("cannot be zero", function(n) { return 0 === n | |
}); | |
//------------------- TEST | |
var influences = [ | |
['Lisp','SmallTalk'], | |
['Lisp','Scheme'], | |
['SmallTalk','Self'], | |
['Scheme','JavaScrpt'], | |
['Scheme','Lua'], | |
['Self','Lua'], | |
['Self','JavaScrpt'] | |
] | |
function nexts(graph,node){ | |
if(_.isEmpty(graph)) return []; | |
var pair = _.first(graph); | |
var from = _.first(pair); | |
var to = second(pair); | |
var more = _.rest(graph); | |
if(_.isEqual(node,from)) | |
return construct(to,nexts(more,node)); | |
else | |
return nexts(more,node); | |
} | |
var data = nexts(influences,'Lisp'); | |
note(data); | |
function depthSearch(graph,nodes,seen){ | |
if(_.isEmpty(nodes)) return rev(seen); | |
var node = _.first(nodes); | |
var more = _.rest(nodes); | |
if(_.contains(seen,node)) | |
return depthSearch(graph,more,seen); | |
else | |
return depthSearch(graph, | |
cat(nexts(graph,node),more), | |
construct(node,seen)); | |
} | |
data = depthSearch(influences,['Lisp'],[]); | |
note(data); | |
data = depthSearch(influences,['SmallTalk','Self'],[]); | |
note(data); | |
data = depthSearch(construct(['Lua','Io'],influences),['Lisp'],[]); | |
note(data); | |
data = depthSearch(influences,['JavaScrpt'],[]); | |
note(data); | |
function andify(/* preds */){ | |
var preds = _.toArray(arguments); | |
return function(/* args */){ | |
var args = _.toArray(arguments); | |
var everything = function(ps,truth){ | |
if(_.isEmpty(ps)) | |
return truth; | |
else | |
return _.every(args,_.first(ps)) | |
&& everything(_.rest(ps),truth); | |
}; | |
return everything(preds,true); | |
}; | |
} | |
var evenNums = andify(_.isNumber,isEven); | |
data = evenNums(2,2); | |
note(data); | |
function orify(){ | |
var preds = _.toArray(arguments); | |
return function(){ | |
var args = _.toArray(arguments); | |
var something = function(ps,truth){ | |
if(_.isEmpty(ps)) | |
return truth; | |
else | |
return _.some(args,_.first(ps)) | |
|| something(_.rest(ps),truth); | |
} | |
return something(preds,false); | |
} | |
} | |
var zeroOrOdd = orify(isOdd,zero); | |
data = zeroOrOdd(2,2); | |
note(data); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
for fp study