Skip to content

Instantly share code, notes, and snippets.

@zipcode
Created May 29, 2014 22:07
Show Gist options
  • Save zipcode/89b1d41a39f84d3c3614 to your computer and use it in GitHub Desktop.
Save zipcode/89b1d41a39f84d3c3614 to your computer and use it in GitHub Desktop.
Lifting in Javascript
/* Came up with this today */
Function.prototype.lift = function(f) {
return function() {
return this.apply(this, Array.prototype.map.call(arguments, f));
}.bind(this)
}
/* Why!? Well, suppose you've got some function that takes a bunch of ints... */
// cmp :: Int -> Int -> Int
function cmp (a, b) {
console.assert(typeof(a) == "number");
console.assert(typeof(b) == "number");
return a-b;
}
/* But you want to use it on strings... */
// a: String
var a = "5, 4, 3, 2";
// a.split(', ').sort(cmp).join(', ') // breaks!
/* Suppose you had a conversion function */
// int :: String -> Int
function int(x) {
return +x;
}
/* And let's make sort immutable */
// sorted T :: (this: Array[T]) -> (T -> T -> Int) -> Array[T]
Array.prototype.sorted = function () {
return Array.prototype.sort.apply(this.copy(), arguments);
}
/* Now we want to use a comparator of this type
cmp :: String -> String -> Int
So how do we do that? Like this! */
var cmpStrings = cmp.lift(int);
/*
This maps the *arguments* of cmp! It's like doing this:
function cmpStrings(a, b) { return cmp(int(a), int(b)) }
Putting it all together:
*/
"5, 4, 3, 2, 1".split(', ').sorted(cmp.lift(int)).join(', ');
// "1, 2, 3, 4, 5"
/* Nice! */
@zipcode
Copy link
Author

zipcode commented May 29, 2014

var b = [{name: 'hi', id: 2}, {name: 'bye', id: 1}]
b.sorted(cmp.lift(function(x) { return x.id }))

Handy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment