Skip to content

Instantly share code, notes, and snippets.

@poetix
Created March 10, 2011 10:44
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 poetix/863932 to your computer and use it in GitHub Desktop.
Save poetix/863932 to your computer and use it in GitHub Desktop.
Javascript Combinator examples
"use strict";
// compose :: (b -> c) -> (a -> b) -> (a -> c)
function compose(g, f) {
return function() {
return g(f.apply(f, arguments));
};
}
// each :: [a] -> (a -> _) -> _
function each(xs, f) {
var i;
for (i = 0; i < xs.length; ++i) {
f(xs[i], i);
}
}
// map :: [a] -> (a -> b) -> [b]
function map(f, xs) {
var i, result = [];
each(xs, function(x, i) {
result[i] = f(x);
});
return result;
}
// concatMap :: [a] -> (a -> [b]) -> [b]
function concatMap(f, xs) {
var k=0, result = [];
each(xs, function(x) {
each(f(x), function(y) {
result[k] = y;
k += 1;
});
});
return result;
}
// listCompose :: (b -> [c]) -> (a -> [b]) -> (a -> [c])
function listCompose(g, f) {
return function() {
return concatMap(g, f.apply(f, arguments));
};
}
// foldr :: (a -> b) -> b -> [a] -> [b]
function foldr(f, a, xs) {
return foldr_(f, a, xs, xs.length - 1);
}
function foldr_(f, a, xs, i) {
var x = xs[i];
a = f(x, a);
if (i === 0) { return a; }
return foldr_(f, a, xs, i - 1);
}
// foldl :: (a -> b) -> b -> [a] -> [b]
function foldl(f, a, xs) {
return foldl_(f, a, xs, 0);
}
function foldl_(f, a, xs, i) {
var x = xs[i]
a = f(x, a);
if (i === xs.length - 1) { return a; }
return foldl_(f, a, xs, i + 1);
}
// makePipe :: ((b -> c) -> (a -> b) -> (a -> c)) -> [(* -> *)] -> (* -> *)
function makePipe(compositor) {
return function() {
var args = Array.prototype.slice.call(arguments),
first = args.shift();
return foldl(compositor, first, args);
};
}
var pipe = makePipe(compose);
var listPipe = makePipe(listCompose);
function add(rhs) {
return function(lhs) {
return lhs + rhs;
};
}
function subtract(rhs) {
return function(lhs) {
return lhs - rhs;
};
}
function multiply(rhs) {
return function(lhs) {
return lhs * rhs;
};
}
var calc = pipe(
add(5),
multiply(7),
subtract(4)
);
print(calc(8));
function sum(seq) {
return foldr(function(a, b) { return a + b; }, 0, seq);
}
function avg(seq) {
return sum(seq) / seq.length;
}
var tryAll = listPipe(
function(a) {
return [a, a + 1, a - 1];
},
function(b) {
return [b, b * 2.0, b / 2.0];
},
function(c) {
return [c, c + 1, c - 1];
}
);
var getResult = pipe(
tryAll,
avg,
print);
getResult(10);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment